From c0e0e805d8f446f33a6cc3281a9f614346ff23a9 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 29 Sep 2016 22:59:12 +0200 Subject: [PATCH 01/18] try switching to StaticArrays --- src/GeometryTypes.jl | 4 ++-- src/types.jl | 54 +++++++++++++++++++++++++++++++++++++------- test/runtests.jl | 2 +- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/GeometryTypes.jl b/src/GeometryTypes.jl index f516f31..4af825f 100644 --- a/src/GeometryTypes.jl +++ b/src/GeometryTypes.jl @@ -1,10 +1,10 @@ VERSION >= v"0.4.0-dev+6521" && __precompile__(true) module GeometryTypes -using FixedSizeArrays +using StaticArrays +using StaticArrays.FixedSizeArrays using ColorTypes using Iterators -import FixedSizeArrays: eltype_or, ndims_or using Compat import Base: ==, diff --git a/src/types.jl b/src/types.jl index 2febb60..123cc62 100644 --- a/src/types.jl +++ b/src/types.jl @@ -14,7 +14,7 @@ Abstract to classify Simplices. The convention for N starts at 1, which means a Simplex has 1 point. A 2-simplex has 2 points, and so forth. This convention is not the same as most mathematical texts. """ -abstract AbstractSimplex{N,T} <: FixedVector{N,T} +abstract AbstractSimplex{T} <: StaticVector{T} """ @@ -33,16 +33,42 @@ This is for a simpler implementation. It applies to infinite dimensions. The structure of this type is designed to allow embedding in higher-order spaces by parameterizing on `T`. """ -immutable Simplex{N,T} <: AbstractSimplex{N,T} +immutable Simplex{N,T} <: AbstractSimplex{T} _::NTuple{N,T} end -immutable Normal{N, T} <: FixedVector{N, T} +immutable Normal{N, T} <: StaticVector{T} _::NTuple{N, T} end -immutable TextureCoordinate{N, T} <: FixedVector{N, T} + +@inline (::Type{Normal}){S}(x::NTuple{S}) = Normal{S}(x) +@inline (::Type{Normal{S}}){S, T}(x::NTuple{S,T}) = Normal{S,T}(x) +@inline (::Type{Normal{S}}){S, T <: Tuple}(x::T) = Normal{S,promote_tuple_eltype(T)}(x) + +Base.@pure Base.size{S}(::Union{Normal{S},Type{Normal{S}}}) = (S, ) +Base.@pure Base.size{S,T}(::Type{Normal{S,T}}) = (S,) + +Base.@propagate_inbounds function Base.getindex(v::Normal, i::Integer) + v.data[i] +end +@inline Base.Tuple(v::Normal) = v.data + +immutable TextureCoordinate{N, T} <: StaticVector{T} _::NTuple{N, T} end +@inline (::Type{TextureCoordinate}){S}(x::NTuple{S}) = TextureCoordinate{S}(x) +@inline (::Type{TextureCoordinate{S}}){S, T}(x::NTuple{S,T}) = TextureCoordinate{S,T}(x) +@inline (::Type{TextureCoordinate{S}}){S, T <: Tuple}(x::T) = TextureCoordinate{S,promote_tuple_eltype(T)}(x) + +Base.@pure Base.size{S}(::Union{TextureCoordinate{S},Type{TextureCoordinate{S}}}) = (S, ) +Base.@pure Base.size{S,T}(::Type{TextureCoordinate{S,T}}) = (S,) + +Base.@propagate_inbounds function Base.getindex(v::TextureCoordinate, i::Integer) + v.data[i] +end + +@inline Base.Tuple(v::TextureCoordinate) = v.data + """ A Face is typically used when constructing subtypes of `AbstractMesh` where @@ -54,9 +80,21 @@ Face is parameterized by: * `O` - The offset relative to Julia arrays. This helps reduce copying when communicating with 0-indexed systems such ad OpenGL. """ -immutable Face{N, T, IndexOffset} <: FixedVector{N, T} +immutable Face{N, T, IndexOffset} <: StaticVector{T} _::NTuple{N, T} end +@inline (::Type{Face}){S}(x::NTuple{S}) = Face{S}(x) +@inline (::Type{Face{S, O}}){S, T, O}(x::NTuple{S,T}) = Face{S,T, O}(x) +@inline (::Type{Face{S, O}}){S, T <: Tuple, O}(x::T) = Face{S,promote_tuple_eltype(T), O}(x) + +Base.@pure Base.size{S}(::Union{Face{S},Type{Face{S}}}) = (S, ) +Base.@pure Base.size{S,T}(::Type{Face{S,T}}) = (S,) + +Base.@propagate_inbounds function Base.getindex(v::Face, i::Integer) + v.data[i] +end + +@inline Base.Tuple(v::Face) = v.data """ A `HyperRectangle` is a generalization of a rectangle into N-dimensions. @@ -80,7 +118,7 @@ A `HyperSphere` is a generalization of a sphere into N-dimensions. A `center` and radius, `r`, must be specified. """ immutable HyperSphere{N, T} <: GeometryPrimitive{N, T} - center::Point{N, T} + center::Face{N, T} r::T end @@ -104,13 +142,13 @@ immutable Quad{T} <: GeometryPrimitive{3, T} end immutable Pyramid{T} <: GeometryPrimitive{3, T} - middle::Point{3, T} + middle::Face{3, T} length::T width ::T end immutable Particle{N, T} <: GeometryPrimitive{N, T} - position::Point{N, T} + position::Face{N, T} velocity::Vec{N, T} end diff --git a/test/runtests.jl b/test/runtests.jl index ce562f3..4b19f5c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,7 +3,6 @@ using FactCheck import Base.Test.@inferred facts("GeometryTypes") do - include("polygons.jl") include("hyperrectangles.jl") include("faces.jl") include("meshes.jl") @@ -17,6 +16,7 @@ facts("GeometryTypes") do include("convexhulls.jl") include("gjk.jl") include("lines.jl") + include("polygons.jl") end FactCheck.exitstatus() From 658717bb719e3d99e81aa088a5016d545dae5bd0 Mon Sep 17 00:00:00 2001 From: Simon Danisch Date: Tue, 22 Nov 2016 17:43:22 +0100 Subject: [PATCH 02/18] test pass with new OffsetInteger for facetype --- src/GeometryTypes.jl | 6 ++- src/algorithms.jl | 87 +++++++++++++++++++++++++++++++++-- src/checkbounds.jl | 23 ---------- src/decompose.jl | 62 +++++++++++-------------- src/faces.jl | 96 +++++++++++++++++++++++---------------- src/polygons.jl | 4 +- src/slice.jl | 57 ----------------------- src/typealias.jl | 13 ++++-- src/types.jl | 17 ++++++- test/decompose.jl | 30 +++++++----- test/faces.jl | 36 +++++++-------- test/meshes.jl | 106 ++++++++++++++++++++++--------------------- 12 files changed, 288 insertions(+), 249 deletions(-) diff --git a/src/GeometryTypes.jl b/src/GeometryTypes.jl index cde1d90..a7b18a0 100644 --- a/src/GeometryTypes.jl +++ b/src/GeometryTypes.jl @@ -183,6 +183,10 @@ export AABB, width, widths, xwidth, - yheight + yheight, + OffsetInteger, + ZeroIndex, + OneIndex, + GLIndex end # module diff --git a/src/algorithms.jl b/src/algorithms.jl index eb3d123..0ae8940 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -7,9 +7,11 @@ normals{VT,FD,FT,FO}(vertices::Vector{Point{3, VT}}, Compute all vertex normals. """ -function normals{VT,FD,FT,FO}(vertices::Vector{Point{3, VT}}, - faces::Vector{Face{FD,FT,FO}}, - NT = Normal{3, VT}) +function normals{VT, F <: Face}( + vertices::AbstractVector{Point{3, VT}}, + faces::AbstractVector{F}, + NT = Normal{3, VT} + ) normals_result = zeros(Point{3, VT}, length(vertices)) # initilize with same type as verts but with 0 for face in faces v = vertices[face] @@ -17,11 +19,86 @@ function normals{VT,FD,FT,FO}(vertices::Vector{Point{3, VT}}, a = v[2] - v[1] b = v[3] - v[1] n = cross(a,b) - for i =1:FD - fi = onebased(face, i) + for i =1:length(F) + fi = face[i] normals_result[fi] = normals_result[fi] + n end end map!(normalize, normals_result) map(NT, normals_result) end + + +""" +Slice an AbstractMesh at the specified Z axis value. +Returns a Vector of LineSegments generated from the faces at the specified +heights. Note: This will not slice in-plane faces. +""" +function Base.slice{VT<:AbstractFloat,FT<:Integer}(mesh::AbstractMesh{Point{3,VT}, Face{3, FT}}, height::Number) + + height_ct = length(height) + # intialize the LineSegment array + slice = Simplex{2,Point{2,VT}}[] + + for face in mesh.faces + v1,v2,v3 = mesh.vertices[face] + zmax = max(v1[3], v2[3], v3[3]) + zmin = min(v1[3], v2[3], v3[3]) + if height > zmax + continue + elseif zmin <= height + if v1[3] < height && v2[3] >= height && v3[3] >= height + p1 = v1 + p2 = v3 + p3 = v2 + elseif v1[3] > height && v2[3] < height && v3[3] < height + p1 = v1 + p2 = v2 + p3 = v3 + elseif v2[3] < height && v1[3] >= height && v3[3] >= height + p1 = v2 + p2 = v1 + p3 = v3 + elseif v2[3] > height && v1[3] < height && v3[3] < height + p1 = v2 + p2 = v3 + p3 = v1 + elseif v3[3] < height && v2[3] >= height && v1[3] >= height + p1 = v3 + p2 = v2 + p3 = v1 + elseif v3[3] > height && v2[3] < height && v1[3] < height + p1 = v3 + p2 = v1 + p3 = v2 + else + continue + end + + start = Point{2,VT}(p1[1] + (p2[1] - p1[1]) * (height - p1[3]) / (p2[3] - p1[3]), + p1[2] + (p2[2] - p1[2]) * (height - p1[3]) / (p2[3] - p1[3])) + finish = Point{2,VT}(p1[1] + (p3[1] - p1[1]) * (height - p1[3]) / (p3[3] - p1[3]), + p1[2] + (p3[2] - p1[2]) * (height - p1[3]) / (p3[3] - p1[3])) + + push!(slice, Simplex{2,Point{2,VT}}(start, finish)) + end + end + + return slice +end + + +# TODO this should be checkbounds(Bool, ...) +""" +``` +checkbounds{VT,FT,FD,FO}(m::AbstractMesh{VT,Face{FD,FT,FO}}) +``` + +Check the `Face` indices to ensure they are in the bounds of the vertex +array of the `AbstractMesh`. +""" +function Base.checkbounds{VT, FD, FT}(m::AbstractMesh{VT, Face{FD, FT}}) + isempty(faces(m)) && return true # nothing to worry about I guess + flat_inds = reinterpret(FT, faces(m)) + checkbounds(Bool, vertices(m), flat_inds) +end diff --git a/src/checkbounds.jl b/src/checkbounds.jl index e6557e1..e69de29 100644 --- a/src/checkbounds.jl +++ b/src/checkbounds.jl @@ -1,23 +0,0 @@ -""" -``` -checkbounds{VT,FT,FD,FO}(m::AbstractMesh{VT,Face{FD,FT,FO}}) -``` - -Check the `Face` indices to ensure they are in the bounds of the vertex -array of the `AbstractMesh`. -""" -function Base.checkbounds{VT,FT,FD,FO}(m::AbstractMesh{VT,Face{FD,FT,FO}}) - isempty(faces(m)) && return true # nothing to worry about I guess - - # index max and min - const i = one(FO) + FO # normalize face offset - s = length(vertices(m)) + FO - - for face in faces(m) - # I hope this is unrolled - for elt in face - i <= elt && elt <= s || return false - end - end - return true -end diff --git a/src/decompose.jl b/src/decompose.jl index 07c4e60..507f1dc 100644 --- a/src/decompose.jl +++ b/src/decompose.jl @@ -48,18 +48,14 @@ decompose{N, FT1, FT2, O1, O2}(::Type{Face{3, FT1, O1}}, ``` Triangulate an N-Face into a tuple of triangular faces. """ -@generated function decompose{N, FT1, FT2, O1, O2}(::Type{Face{3, FT1, O1}}, - f::Face{N, FT2, O2}) +@generated function decompose{N, FT1, FT2}(::Type{Face{3, FT1}}, + f::Face{N, FT2}) 3 <= N || error("decompose not implented for N <= 3 yet. N: $N")# other wise degenerate v = Expr(:tuple) - append!(v.args, [ - :(Face{3,FT1,O1}( - offsetbased(f,1, O1), - offsetbased(f,$(i-1), O1), - offsetbased(f,$i, O1) - )) for i = 3:N] - ) + for i = 3:N + push!(v.args, :(Face{3, FT1}(f[1], f[$(i-1)], f[$i]))) + end v end @@ -71,24 +67,18 @@ decompose{N, FT1, FT2, O1, O2}(::Type{Face{2, FT1, O1}}, Extract all line segments in a Face. """ -@generated function decompose{N, FT1, FT2, O1, O2}(::Type{Face{2, FT1, O1}}, - f::Face{N, FT2, O2}) +@generated function decompose{N, FT1, FT2}( + ::Type{Face{2, FT1}}, + f::Face{N, FT2} + ) 2 <= N || error("decompose not implented for N <= 2 yet. N: $N")# other wise degenerate v = Expr(:tuple) - append!(v.args, [ - :(Face{2,$FT1,$O1}( - offsetbased(f, $i , O1), - offsetbased(f, $(i+1), O1), - )) for i = 1:N-1] - ) + for i = 1:N-1 + push!(v.args, :(Face{2, $FT1}(f[$i], f[$(i+1)]))) + end # connect vertices N and 1 - push!(v.args, - :(Face{2,$FT1,$O1}( - offsetbased(f, N, O1), - offsetbased(f, 1, O1) - )) - ) + push!(v.args, :(Face{2, $FT1}(f[$N], f[1]))) v end @@ -193,10 +183,10 @@ end """ Get decompose a `HyperRectangle` into faces. """ -function decompose{N, T, O, T2}( - FT::Type{Face{N, T, O}}, rect::HyperRectangle{3, T2} +function decompose{N, T, T2}( + FT::Type{Face{N, T}}, rect::HyperRectangle{3, T2} ) - faces = Face{4, Int, 0}[ + faces = Face{4, Int}[ (1,2,4,3), (2,4,8,6), (4,3,7,8), @@ -224,7 +214,7 @@ function decompose{T<:Normal}(::Type{T}, r::SimpleRectangle, resolution=(2,2)) end function decompose{T<:Face}(::Type{T}, r::SimpleRectangle, resolution=(2,2)) w,h = resolution - faces = vec([Face{4, Int, 0}( + faces = vec([Face{4, Int}( sub2ind(resolution, i, j), sub2ind(resolution, i+1, j), sub2ind(resolution, i+1, j+1), sub2ind(resolution, i, j+1) ) for i=1:(w-1), j=1:(h-1)] @@ -263,11 +253,11 @@ function decompose{NT}(T::Type{Normal{3, NT}}, q::Quad) T[normal for i=1:4] end -decompose{FT, IO}(T::Type{Face{3, FT, IO}}, q::Quad) = T[ - Face{3, Int, 0}(1,2,3), Face{3, Int, 0}(3,4,1) +decompose{FT}(T::Type{Face{3, FT}}, q::Quad) = T[ + Face{3, FT}(1,2,3), Face{3, FT}(3,4,1) ] -decompose{FT, IO}(T::Type{Face{4, FT, IO}}, q::Quad) = T[ - Face{4, Int, 0}(1,2,3,4) +decompose{FT}(T::Type{Face{4, FT}}, q::Quad) = T[ + Face{4, FT}(1, 2, 3, 4) ] decompose{ET}( T::Type{UV{ET}}, q::Quad) = T[ T(0,0), T(0,1), T(1,1), T(1,0) @@ -280,8 +270,8 @@ decompose{ET}(T::Type{UVW{ET}}, q::Quad) = T[ q.downleft + q.width ] -function decompose{FT, IO}(T::Type{Face{3, FT, IO}}, r::Pyramid) - reinterpret(T, collect(map(FT, (1:18)+IO))) +function decompose{FT}(T::Type{Face{3, FT}}, r::Pyramid) + reinterpret(T, collect(map(FT, (1:18)))) end @@ -298,7 +288,7 @@ function decompose{VT}(T::Type{Point{3, VT}}, mesh::AbstractMesh) end # gets the wanted face type -function decompose{N, FT, Offset}(T::Type{Face{N, FT, Offset}}, mesh::AbstractMesh) +function decompose{N, FT}(T::Type{Face{N, FT}}, mesh::AbstractMesh) fs = faces(mesh) eltype(fs) == T && return fs return decompose(T, fs) @@ -390,8 +380,8 @@ function decompose{FT<:Face}(::Type{FT}, s::Sphere, facets=12) i2 = sub2ind((facets,), j, next_index) i3 = (j != facets) ? sub2ind((facets,), j+1, i) : psydo_triangle_i i6 = (j != facets) ? sub2ind((facets,), j+1, next_index) : psydo_triangle_i - indexes[index] = FT(Triangle{FTE}(i1,i2,i3)) # convert to required Face index offset - indexes[index+1] = FT(Triangle{FTE}(i3,i2,i6)) + indexes[index] = FT(i1,i2,i3) # convert to required Face index offset + indexes[index+1] = FT(i3,i2,i6) index += 2 end end diff --git a/src/faces.jl b/src/faces.jl index 1df7aa9..632a262 100644 --- a/src/faces.jl +++ b/src/faces.jl @@ -1,51 +1,71 @@ -""" -Given an Array, `a`, and a face, `f`, return a tuple of numbers -interpreting the values and offset of the face as indices into `A`. - -Note: This is not bounds checked. It is recommended that you use -`checkbounds` to confirm the indices are safe for loops. -Also be aware when writing generic code that faces may be of more than -3 vertices. -""" -@generated function Base.getindex{T,N,FD,FT,Offset}(a::Array{T,N}, - f::Face{FD, FT, Offset}) - v = Expr(:tuple) - for i = 1:FD - push!(v.args, Expr(:call, Base.unsafe_getindex, :a, :(Int(f[$i])-Int(Offset)))) - end - :($(v)::NTuple{FD,T}) +import Base: +, -, abs, *, /, div, convert, ==, <=, >=, show + +function show{O, T}(io::IO, oi::OffsetInteger{O, T}) + i = T(oi) + print(io, "|$(i)-$(O)|") end -function setindex!{T,N,FD,FT,Offset}(a::Array{T,N}, b::Array{T,N}, f::Face{FD, FT, Offset}) - for i=1:FD - a[onebased(f,i)] = b[i] - end +# constructors and conversion + +(::Type{T}){T <: OffsetInteger}(x::T) = x + +function (::Type{OffsetInteger{O}}){O, T <: Integer}(x::T) + OffsetInteger{O, T}(x) end -convert{T1<:Face}(::Type{T1}, f::T1) = f -convert{T1<:Face, T2<:Face}(::Type{T1}, f::T2) = T1(f) +function (::Type{OffsetInteger{O, T}}){O, T}(x::OffsetInteger) + OffsetInteger{O, T}(T(x)) +end +function (::Type{OffsetInteger{O1}}){O1, O2, T}(x::OffsetInteger{O2, T}) + OffsetInteger{O1}(T(x)) +end -# Silly duplication, but call(::FixedVector, ::Any) = convert is overloaded in FixedSizeArrays -@compat (::Type{F}){F<:Face}(f::F) = f +convert{T <: Integer, O, T2}(::Type{T}, x::OffsetInteger{O, T2}) = T(x.i + O) +convert{O, T}(::Type{OffsetInteger{O, T}}, x::Int) = OffsetInteger{O, T}(T(x)) +convert{O, T <: Integer}(::Type{OffsetInteger{O, T}}, x::T) = OffsetInteger{O, T}(x) -@compat function (::Type{Face{N, T, O}}){T, T2, O, N}(f::Face{N, T2, O}) - Face{N, T, O}(convert(NTuple{N, T}, getfield(f, 1))) + +# basic operators +for op in (:(-), :abs) + @eval $(op){T <: OffsetInteger}(x::T) = T($(op)(x.i)) end -immutable IndexConvertFunc{T1, T2} - f::T2 +for op in (:(+), :(-), :(*), :(/), :div) + @eval begin + @inline function $(op){O}(x::OffsetInteger{O}, y::OffsetInteger{O}) + OffsetInteger{O}($op(x.i, y.i)) + end + end end -@compat function (ifunc::IndexConvertFunc{Face{N,T1,O1}, Face{N,T2,O2}}){N,T1,T2,O1,O2}(i) - Int(ifunc.f[i])+Int(O1)-Int(O2) +for op in (:(==), :(>=), :(<=)) + @eval begin + @inline function $(op){O}(x::OffsetInteger{O}, y::OffsetInteger{O}) + $op(x.i, y.i) + end + end end -@compat function (T::Type{Face{N, T1, O1}}){N, T1, O1, F<:Face}(f::F) - map(IndexConvertFunc{T,F}(f), T) + + +function Base.promote_type{T <: Int, OI <: OffsetInteger}(::Type{T}, ::Type{OI}) + T end +function Base.promote_type{T <: Int, OI <: OffsetInteger}(::Type{OI}, ::Type{T}) + T +end + -function Face{T<:Number}(vals::T...) - Face{length(vals), T, 0}(vals...) +@generated function Base.getindex{N}( + A::AbstractArray, f::Face{N} + ) + v = Expr(:tuple) + for i = 1:N + push!(v.args, :(A[f[$i]])) + end + :($(v)) end -onebased{N,T,Offset}(face::Face{N,T,Offset}, i) = T(Int(face[i]) - Int(Offset)) -zerobased{N,T,Offset}(face::Face{N,T,Offset}, i) = T(Int(face[i]) - Int(Offset) - 1) -offsetbased{N,T,Offset}(face::Face{N,T,Offset}, i, offset) = T(Int(face[i]) - Int(Offset) + Int(offset)) -export onebased, zerobased +function setindex!{N}(a::AbstractArray, b::AbstractArray, f::Face{N}) + for i = 1:N + a[f[i]] = b[i] + end + b +end diff --git a/src/polygons.jl b/src/polygons.jl index aaee4b0..23409ba 100644 --- a/src/polygons.jl +++ b/src/polygons.jl @@ -69,7 +69,7 @@ Triangulates a Polygon given as a `contour`::AbstractArray{Point} without holes. It will return a Vector{`facetype`}, defining indexes into `contour` """ function polygon2faces{P<:Point}( - contour::AbstractArray{P}, facetype=GLTriangle + contour::AbstractArray{P}, facetype = GLTriangle ) #= allocate and initialize list of Vertices in polygon =# result = facetype[] @@ -111,7 +111,7 @@ function polygon2faces{P<:Point}( #= true names of the vertices =# a = V[u]; b = V[v]; c = V[w]; #= output Triangle =# - push!(result, facetype(Triangle{Int}(a, b, c))) + push!(result, facetype(a, b, c)) #= remove v from remaining polygon =# s = v; t = v+1 while t<=nv diff --git a/src/slice.jl b/src/slice.jl index 5401998..e69de29 100644 --- a/src/slice.jl +++ b/src/slice.jl @@ -1,57 +0,0 @@ -""" -Slice an AbstractMesh at the specified Z axis value. -Returns a Vector of LineSegments generated from the faces at the specified -heights. Note: This will not slice in-plane faces. -""" -function Base.slice{VT<:AbstractFloat,FT<:Integer,O}(mesh::AbstractMesh{Point{3,VT},Face{3,FT,O}}, height::Number) - - height_ct = length(height) - # intialize the LineSegment array - slice = Simplex{2,Point{2,VT}}[] - - for face in mesh.faces - v1,v2,v3 = mesh.vertices[face] - zmax = max(v1[3], v2[3], v3[3]) - zmin = min(v1[3], v2[3], v3[3]) - if height > zmax - continue - elseif zmin <= height - if v1[3] < height && v2[3] >= height && v3[3] >= height - p1 = v1 - p2 = v3 - p3 = v2 - elseif v1[3] > height && v2[3] < height && v3[3] < height - p1 = v1 - p2 = v2 - p3 = v3 - elseif v2[3] < height && v1[3] >= height && v3[3] >= height - p1 = v2 - p2 = v1 - p3 = v3 - elseif v2[3] > height && v1[3] < height && v3[3] < height - p1 = v2 - p2 = v3 - p3 = v1 - elseif v3[3] < height && v2[3] >= height && v1[3] >= height - p1 = v3 - p2 = v2 - p3 = v1 - elseif v3[3] > height && v2[3] < height && v1[3] < height - p1 = v3 - p2 = v1 - p3 = v2 - else - continue - end - - start = Point{2,VT}(p1[1] + (p2[1] - p1[1]) * (height - p1[3]) / (p2[3] - p1[3]), - p1[2] + (p2[2] - p1[2]) * (height - p1[3]) / (p2[3] - p1[3])) - finish = Point{2,VT}(p1[1] + (p3[1] - p1[1]) * (height - p1[3]) / (p3[3] - p1[3]), - p1[2] + (p3[2] - p1[2]) * (height - p1[3]) / (p3[3] - p1[3])) - - push!(slice, Simplex{2,Point{2,VT}}(start, finish)) - end - end - - return slice -end diff --git a/src/typealias.jl b/src/typealias.jl index 8bad8e2..9a3901a 100644 --- a/src/typealias.jl +++ b/src/typealias.jl @@ -27,10 +27,15 @@ An alias for a one-simplex, corresponding to LineSegment{T} -> Simplex{2,T}. """ typealias LineSegment{T} Simplex{2,T} -typealias Triangle{T} Face{3, T, 0} -typealias GLFace{Dim} Face{Dim, Cuint, -1} #offset is relative to julia, so -1 is 0-indexed -typealias GLTriangle Face{3, Cuint, -1} -typealias GLQuad Face{4, Cuint, -1} + +typealias ZeroIndex{T} OffsetInteger{1, T} +typealias OneIndex{T} OffsetInteger{0, T} +typealias GLIndex ZeroIndex{Cuint} + +typealias Triangle{T} Face{3, T} +typealias GLFace{Dim} Face{Dim, GLIndex} #offset is relative to julia, so -1 is 0-indexed +typealias GLTriangle Face{3, GLIndex} +typealias GLQuad Face{4, GLIndex} typealias Cube{T} HyperCube{3, T} diff --git a/src/types.jl b/src/types.jl index 2febb60..97e45fe 100644 --- a/src/types.jl +++ b/src/types.jl @@ -44,6 +44,7 @@ immutable TextureCoordinate{N, T} <: FixedVector{N, T} _::NTuple{N, T} end + """ A Face is typically used when constructing subtypes of `AbstractMesh` where the `Face` should not reproduce the vertices, but rather index into them. @@ -51,13 +52,25 @@ Face is parameterized by: * `N` - The number of vertices in the face. * `T` - The type of the indices in the face, a subtype of Integer. + +""" +immutable Face{N, T} <: FixedVector{N, T} + _::NTuple{N, T} +end + +""" +OffsetInteger type mainly for indexing. * `O` - The offset relative to Julia arrays. This helps reduce copying when communicating with 0-indexed systems such ad OpenGL. """ -immutable Face{N, T, IndexOffset} <: FixedVector{N, T} - _::NTuple{N, T} +immutable OffsetInteger{O, T <: Integer} <: Integer + i::T + function OffsetInteger(x::Integer) + new(x - O) + end end + """ A `HyperRectangle` is a generalization of a rectangle into N-dimensions. Formally it is the cartesian product of intervals, which is represented by the diff --git a/test/decompose.jl b/test/decompose.jl index 82eaae2..aae62fe 100644 --- a/test/decompose.jl +++ b/test/decompose.jl @@ -16,13 +16,18 @@ end end @testset "Faces" begin - @test decompose(GLTriangle, Face{4, Int, 0}(1,2,3,4)) == (Face{3,UInt32,-1}(0,1,2), Face{3,UInt32,-1}(0,2,3)) - @test decompose(Face{3,Int,-1}, Face{4, Int, -1}(1,2,3,4)) == (Face{3,Int,-1}(1,2,3),Face{3,Int,-1}(1,3,4)) - @test decompose(Face{3,Int,2}, Face{4, Int, 1}(1,2,3,4)) == (Face{3,Int,2}(2,3,4),Face{3,Int,2}(2,4,5)) - @test decompose(Face{2,Int,0}, Face{4, Int, 0}(1,2,3,4)) == (Face{2,Int,0}(1,2), - Face{2,Int,0}(2,3), - Face{2,Int,0}(3,4), - Face{2,Int,0}(4,1)) + @test decompose(GLTriangle, Face{4, Int}(1,2,3,4)) == (GLTriangle(1,2,3), GLTriangle(1,3,4)) + @test decompose(Face{3, ZeroIndex{Int}}, Face{4, ZeroIndex{Int}}(1,2,3,4)) == (Face{3,ZeroIndex{Int}}(1,2,3), Face{3, ZeroIndex{Int}}(1,3,4)) + @test decompose(Face{3, OffsetInteger{3, Int}}, Face{4, OffsetInteger{2, Int}}(1,2,3,4)) == ( + Face{3, OffsetInteger{3, Int}}(1,2,3), + Face{3, OffsetInteger{3, Int}}(1,3,4) + ) + @test decompose(Face{2, Int}, Face{4, Int}(1,2,3,4)) == ( + Face{2, Int}(1,2), + Face{2, Int}(2,3), + Face{2, Int}(3,4), + Face{2, Int}(4,1) + ) end @testset "Simplex" begin @@ -59,8 +64,8 @@ end ] @test points == point_target - faces = decompose(Face{3, Int, 0}, mesh) - face_target = Face{3, Int, 0}[ + faces = decompose(Face{3, Int}, mesh) + face_target = Face{3, Int}[ (1,2,5) (1,5,4) (2,3,6) @@ -120,11 +125,11 @@ end @test normals(vertices(r), faces(r), Normal{3, Float32}) == n32 @test normals(vertices(r), faces(r), Normal{3, Float64}) == n64 - r = PlainMesh{Float64, Face{3, UInt32, 0}}(centered(HyperRectangle)) + r = PlainMesh{Float64, Face{3, UInt32}}(centered(HyperRectangle)) @test normals(vertices(r), faces(r), Normal{3, Float32}) == n32 @test normals(vertices(r), faces(r), Normal{3, Float64}) == n64 - r = PlainMesh{Float16, Face{3, UInt64, -1}}(centered(HyperRectangle)) + r = PlainMesh{Float16, Face{3, ZeroIndex{UInt64}}}(centered(HyperRectangle)) @test normals(vertices(r), faces(r), Normal{3, Float32}) == n32 @test normals(vertices(r), faces(r), Normal{3, Float64}) == n64 @@ -150,7 +155,7 @@ end @test points == point_target faces = decompose(GLTriangle, sphere, 3) - face_target = GLTriangle[ + face_target = NTuple{3, Cuint}[ (0,3,1) (1,3,4) (3,6,4) @@ -170,6 +175,7 @@ end (8,2,9) (9,2,9) ] + face_target = reinterpret(GLTriangle, face_target) @test faces == face_target points = decompose(Point2f0, Circle(Point2f0(0), 0f0), 20) diff --git a/test/faces.jl b/test/faces.jl index d2b818d..3184d73 100644 --- a/test/faces.jl +++ b/test/faces.jl @@ -1,24 +1,24 @@ @testset "faces" begin -@testset "constructors" begin - f1 = Face(1,2,3) - @test f1 == Face{3,Int,0}(1,2,3) - @test Face{3,Int,0}(f1) == f1 - @test Face{3,UInt8,0}(f1) == Face{3,UInt8,0}(1,2,3) - @test Face{3,Int,-1}(f1) == Face{3,Int,-1}(0,1,2) -end + @testset "constructors" begin + f1 = Face(1,2,3) + @test Face{3, ZeroIndex{Int}}(f1) == Face{3, Int}(1,2,3) + # round trip + i = 2 + tmp = Face{3, OffsetInteger{3, Int32}}(Face{3}(ZeroIndex{Int}(i))) + @test Int(tmp[1]) == i + end -@testset "getindex" begin - a = [1,2,3,4] - @test a[Face{3,Int,0}(1,2,3)] == (1,2,3) - @test a[Face{3,Int,-1}(0,1,2)] == (1,2,3) - @test a[Face{3,Int,1}(2,3,4)] == (1,2,3) -end + @testset "getindex" begin + a = [1,2,3,4] + @test a[Face{3, Int}(1,2,3)] == (1,2,3) + @test a[Face{3, ZeroIndex{Int}}(1,2,3)] == (1,2,3) + end -@testset "setindex" begin - a = [1,2,3,4] - a[Face(1,2,3)] = [7,6,5] - @test a == [7,6,5,4] -end + @testset "setindex" begin + a = [1,2,3,4] + a[Face(1,2,3)] = [7,6,5] + @test a == [7,6,5,4] + end end \ No newline at end of file diff --git a/test/meshes.jl b/test/meshes.jl index 9ca5f22..68f9616 100644 --- a/test/meshes.jl +++ b/test/meshes.jl @@ -20,7 +20,7 @@ @test vertextype(axis) == Point{3, Float32} @test normaltype(axis) == Normal{3, Float32} - @test facetype(axis) == Face{3, Cuint, -1} + @test facetype(axis) == Face{3, GLIndex} @test hasvertices(axis) @test hasfaces(axis) @test hasnormals(axis) @@ -43,36 +43,38 @@ end @testset "Primitives" begin # issue #16 - #m = HomogenousMesh{Point{3,Float64},Face{3,Int,0}}(Sphere(Point(0,0,0), 1)) + #m = HomogenousMesh{Point{3,Float64},Face{3, Int}}(Sphere(Point(0,0,0), 1)) #@fact length(vertices(m)) --> 145 #@fact length(faces(m)) --> 288 end @testset "Slice" begin - test_mesh = HomogenousMesh(Point{3,Float64}[ - Point{3,Float64}(0.0,0.0,10.0), - Point{3,Float64}(0.0,10.0,10.0), - Point{3,Float64}(0.0,0.0,0.0), - Point{3,Float64}(0.0,10.0,0.0), - Point{3,Float64}(10.0,0.0,10.0), - Point{3,Float64}(10.0,10.0,10.0), - Point{3,Float64}(10.0,0.0,0.0), - Point{3,Float64}(10.0,10.0,0.0), - ],Face{3,Int,0}[ - Face{3,Int,0}(3,7,5) - Face{3,Int,0}(1,3,5) - Face{3,Int,0}(1,2,3) - Face{3,Int,0}(2,4,3) - Face{3,Int,0}(1,5,6) - Face{3,Int,0}(2,1,6) - Face{3,Int,0}(4,8,3) - Face{3,Int,0}(3,8,7) - Face{3,Int,0}(7,8,6) - Face{3,Int,0}(7,6,5) - Face{3,Int,0}(2,6,4) - Face{3,Int,0}(4,6,8)] - ) + test_mesh = HomogenousMesh( + Point{3,Float64}[ + Point{3,Float64}(0.0,0.0,10.0), + Point{3,Float64}(0.0,10.0,10.0), + Point{3,Float64}(0.0,0.0,0.0), + Point{3,Float64}(0.0,10.0,0.0), + Point{3,Float64}(10.0,0.0,10.0), + Point{3,Float64}(10.0,10.0,10.0), + Point{3,Float64}(10.0,0.0,0.0), + Point{3,Float64}(10.0,10.0,0.0), + ], + Face{3, Int}[ + Face{3, Int}(3,7,5) + Face{3, Int}(1,3,5) + Face{3, Int}(1,2,3) + Face{3, Int}(2,4,3) + Face{3, Int}(1,5,6) + Face{3, Int}(2,1,6) + Face{3, Int}(4,8,3) + Face{3, Int}(3,8,7) + Face{3, Int}(7,8,6) + Face{3, Int}(7,6,5) + Face{3, Int}(2,6,4) + Face{3, Int}(4,6,8) + ]) s1 = slice(test_mesh, 1.0) s2 = slice(test_mesh, 2.0) s3 = slice(test_mesh, 0.0) @@ -93,21 +95,23 @@ end end @testset "checkbounds" begin - m1 = HomogenousMesh([Point{3,Float64}(0.0,0.0,10.0), - Point{3,Float64}(0.0,10.0,10.0), - Point{3,Float64}(0.0,0.0,0.0)], - [Face{3,Int,0}(1,2,3)]) + m1 = HomogenousMesh([Point{3, Float64}(0.0,0.0,10.0), + Point{3, Float64}(0.0,10.0,10.0), + Point{3, Float64}(0.0,0.0,0.0)], + [Face{3, Int}(1,2,3)]) @test checkbounds(m1) - m2 = HomogenousMesh([Point{3,Float64}(0.0,0.0,10.0), - Point{3,Float64}(0.0,10.0,10.0), - Point{3,Float64}(0.0,0.0,0.0)], - [Face{3,Int,-1}(1,2,3)]) - @test !( checkbounds(m2) ) + + m2 = HomogenousMesh([Point{3, Float64}(0.0,0.0,10.0), + Point{3, Float64}(0.0,10.0,10.0), + Point{3, Float64}(0.0,0.0,0.0)], + [Face{3, GLIndex}(5,1,2)]) + @test !checkbounds(m2) + # empty case - m3 = HomogenousMesh([Point{3,Float64}(0.0,0.0,10.0), - Point{3,Float64}(0.0,10.0,10.0), - Point{3,Float64}(0.0,0.0,0.0)], - Face{3,Int,-1}[]) + m3 = HomogenousMesh([Point{3, Float64}(0.0,0.0,10.0), + Point{3, Float64}(0.0,10.0,10.0), + Point{3, Float64}(0.0,0.0,0.0)], + Face{3, GLIndex}[]) @test checkbounds(m3) end @@ -120,19 +124,19 @@ end Point{3,Float64}(10.0,10.0,10.0), Point{3,Float64}(10.0,0.0,0.0), Point{3,Float64}(10.0,10.0,0.0), - ],Face{3,Int,0}[ - Face{3,Int,0}(3,7,5) - Face{3,Int,0}(1,3,5) - Face{3,Int,0}(1,2,3) - Face{3,Int,0}(3,2,4) - Face{3,Int,0}(1,5,6) - Face{3,Int,0}(2,1,6) - Face{3,Int,0}(4,8,3) - Face{3,Int,0}(3,8,7) - Face{3,Int,0}(7,8,6) - Face{3,Int,0}(5,7,6) - Face{3,Int,0}(2,6,4) - Face{3,Int,0}(4,6,8)] + ],Face{3, Int}[ + Face{3, Int}(3,7,5) + Face{3, Int}(1,3,5) + Face{3, Int}(1,2,3) + Face{3, Int}(3,2,4) + Face{3, Int}(1,5,6) + Face{3, Int}(2,1,6) + Face{3, Int}(4,8,3) + Face{3, Int}(3,8,7) + Face{3, Int}(7,8,6) + Face{3, Int}(5,7,6) + Face{3, Int}(2,6,4) + Face{3, Int}(4,6,8)] ) ns = normals(test_mesh.vertices, test_mesh.faces) @test length(ns) == length(test_mesh.vertices) From 8e90457381d9a65ceef0153a2291dca92863d849 Mon Sep 17 00:00:00 2001 From: Simon Danisch Date: Tue, 22 Nov 2016 20:08:23 +0100 Subject: [PATCH 03/18] =?UTF-8?q?add=20raw=20function=C3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.jl b/src/types.jl index 97e45fe..46ce12e 100644 --- a/src/types.jl +++ b/src/types.jl @@ -69,7 +69,7 @@ immutable OffsetInteger{O, T <: Integer} <: Integer new(x - O) end end - +raw(x::OffsetInteger) = x.i """ A `HyperRectangle` is a generalization of a rectangle into N-dimensions. From dfad5b9c62de0fb3719c274ea7dc2dfd3cb380e6 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Fri, 16 Dec 2016 12:43:31 +0100 Subject: [PATCH 04/18] fix test break due to high precision --- test/meshes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/meshes.jl b/test/meshes.jl index e62149a..3d2d364 100644 --- a/test/meshes.jl +++ b/test/meshes.jl @@ -140,9 +140,9 @@ end (2,6,4), (4,6,8) ]) - ns = normals(test_mesh.vertices, test_mesh.faces) + ns = normals(test_mesh.vertices, test_mesh.faces, Normal{3, Float32}) @test length(ns) == length(test_mesh.vertices) - expect = Normal{3, Float64}[ + expect = Normal{3, Float32}[ (-0.408248,-0.408248,0.816497), (-0.816497,0.408248,0.408248), (-0.57735,-0.57735,-0.57735), From b95538ec3bac0c2e175690caa12f8b64ca675f7c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Fri, 16 Dec 2016 14:39:34 +0100 Subject: [PATCH 05/18] use mesh type --- src/polygons.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/polygons.jl b/src/polygons.jl index 23409ba..0b03312 100644 --- a/src/polygons.jl +++ b/src/polygons.jl @@ -73,7 +73,7 @@ function polygon2faces{P<:Point}( ) #= allocate and initialize list of Vertices in polygon =# result = facetype[] - + # the algorithm doesn't like closed contours if isapprox(last(contour), first(contour)) pop!(contour) @@ -142,5 +142,5 @@ end ) faces = polygon2faces(points, facetype(M)) VT = vertextype(M) - GLNormalMesh(faces = faces, vertices = VT[topoint(VT, p) for p in points]) + M(faces = faces, vertices = VT[topoint(VT, p) for p in points]) end From e82ce6d97a703ba054f69e6318f29e0ff70bdbc7 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Fri, 16 Dec 2016 14:39:48 +0100 Subject: [PATCH 06/18] move constructor macro to StaticArrays --- src/types.jl | 76 ++-------------------------------------------------- 1 file changed, 2 insertions(+), 74 deletions(-) diff --git a/src/types.jl b/src/types.jl index b5317a3..9c12526 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1,77 +1,5 @@ -macro fixed_vector(name, parent) - esc(quote - immutable $(name){S, T} <: $(parent){T} - data::NTuple{S, T} - - function $(name)(x::NTuple{S,T}) - new(x) - end - function $(name)(x::NTuple{S}) - new(StaticArrays.convert_ntuple(T, x)) - end - end - @inline function (::Type{$(name){S, T}}){S, T}(x) - $(name){S, T}(ntuple(i-> T(x), Val{S})) - end - @inline function (::Type{$(name){S}}){S, T}(x::T) - $(name){S, T}(ntuple(i-> x, Val{S})) - end - @inline function (::Type{$(name){1, T}}){T}(x::T) - $(name){1, T}((x,)) - end - @inline (::Type{$(name)}){S}(x::NTuple{S}) = $(name){S}(x) - @inline function (::Type{$(name){S}}){S, T <: Tuple}(x::T) - $(name){S, StaticArrays.promote_tuple_eltype(T)}(x) - end - @generated function (::Type{SV}){SV <: $(name)}(x::StaticVector) - len = size_or(SV, size(x))[1] - if length(x) == len - :(SV(Tuple(x))) - elseif length(x) > len - elems = [:(x[$i]) for i = 1:len] - :(SV($(Expr(:tuple, elems...)))) - else - error("Static Vector too short: $x, target type: $SV") - end - end - - Base.@pure Base.size{S}(::Union{$(name){S}, Type{$(name){S}}}) = (S, ) - Base.@pure Base.size{S,T}(::Type{$(name){S, T}}) = (S,) - - Base.@propagate_inbounds function Base.getindex(v::$(name), i::Integer) - v.data[i] - end - @inline Base.Tuple(v::$(name)) = v.data - @inline Base.convert{S, T}(::Type{$(name){S, T}}, x::NTuple{S, T}) = $(name){S, T}(x) - @inline Base.convert{SV <: $(name)}(::Type{SV}, x::StaticVector) = SV(x) - @inline function Base.convert{S, T}(::Type{$(name){S, T}}, x::Tuple) - $(name){S, T}(convert(NTuple{S, T}, x)) - end - # StaticArrays.similar_type{SV <: $(name)}(::Union{SV, Type{SV}}) = $(name) - # function StaticArrays.similar_type{SV <: $(name), T}(::Union{SV, Type{SV}}, ::Type{T}) - # $(name){length(SV), T} - # end - # function StaticArrays.similar_type{SV <: $(name)}(::Union{SV, Type{SV}}, s::Tuple{Int}) - # $(name){s[1], eltype(SV)} - # end - function StaticArrays.similar_type{SV <: $(name), T}(::Union{SV, Type{SV}}, ::Type{T}, s::Tuple{Int}) - $(name){s[1], T} - end - function StaticArrays.similar_type{SV <: $(name)}(::Union{SV, Type{SV}}, s::Tuple{Int}) - $(name){s[1], eltype(SV)} - end - eltype_or(::Type{$(name)}, or) = or - eltype_or{T}(::Type{$(name){TypeVar(:S), T}}, or) = T - eltype_or{S}(::Type{$(name){S, TypeVar(:T)}}, or) = or - eltype_or{S, T}(::Type{$(name){S, T}}, or) = T - - size_or(::Type{$(name)}, or) = or - size_or{T}(::Type{$(name){TypeVar(:S), T}}, or) = or - size_or{S}(::Type{$(name){S, TypeVar(:T)}}, or) = (S,) - size_or{S, T}(::Type{$(name){S, T}}, or) = (S,) - end) -end - +using StaticArrays.FixedSizeArrays +import StaticArrays.FixedSizeArrays: @fixed_vector abstract AbstractDistanceField abstract AbstractUnsignedDistanceField <: AbstractDistanceField From 9d7b6ff8349ab9aba07bed0d6675339906642504 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 30 Mar 2017 15:53:09 +0200 Subject: [PATCH 07/18] fixes for 0.6 --- src/algorithms.jl | 2 +- src/meshes.jl | 4 ++-- src/simplices.jl | 2 +- src/types.jl | 2 +- src/typeutils.jl | 1 + 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/algorithms.jl b/src/algorithms.jl index 786e274..278e801 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -34,7 +34,7 @@ Slice an AbstractMesh at the specified Z axis value. Returns a Vector of LineSegments generated from the faces at the specified heights. Note: This will not slice in-plane faces. """ -function Base.slice{VT<:AbstractFloat,FT<:Integer}(mesh::AbstractMesh{Point{3,VT}, Face{3, FT}}, height::Number) +function slice{VT<:AbstractFloat,FT<:Integer}(mesh::AbstractMesh{Point{3,VT}, Face{3, FT}}, height::Number) height_ct = length(height) # intialize the LineSegment array diff --git a/src/meshes.jl b/src/meshes.jl index 918cff7..69cba12 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -48,7 +48,7 @@ end # Needed to not get into an stack overflow convert{M <: AbstractMesh}(::Type{M}, mesh::AbstractGeometry) = M(mesh) -@compat (::Type{HM1}){HM1 <: AbstractMesh}(mesh::HM1) = mesh +#@compat (::Type{HM1}){HM1 <: AbstractMesh}(mesh::HM1) = mesh """ Uses decompose to get all the converted attributes from the meshtype and @@ -57,7 +57,7 @@ Getindex can be defined for any arbitrary geometric type or exotic mesh type. This way, we can make sure, that you can convert most of the meshes from one type to the other with minimal code. """ -@compat function (::Type{HM1}){HM1 <: AbstractMesh}(primitive::Union{AbstractMesh, GeometryPrimitive}) +@compat function (::Type{HM1}){HM1 <: AbstractMesh}(primitive::GeometryPrimitive) result = Dict{Symbol, Any}() for (field, target_type) in zip(fieldnames(HM1), HM1.parameters) if target_type != Void diff --git a/src/simplices.jl b/src/simplices.jl index e01ecea..f9fa519 100644 --- a/src/simplices.jl +++ b/src/simplices.jl @@ -39,7 +39,7 @@ end # function StaticArrays.similar_type{SV <: Simplex}(::Union{SV, Type{SV}}, s::Tuple{Int}) # Simplex{s[1], eltype(SV)} # end -function StaticArrays.similar_type{SV <: Simplex, T}(::Union{SV, Type{SV}}, ::Type{T}, s::Tuple{Int}) +function StaticArrays.similar_type{SV <: Simplex, T}(::Union{Simplex, Type{Simplex}}, ::Type{T}, s::Tuple{Int}) Simplex{s[1], T} end diff --git a/src/types.jl b/src/types.jl index 9c12526..67b58c8 100644 --- a/src/types.jl +++ b/src/types.jl @@ -9,7 +9,7 @@ Abstract to categorize geometry primitives of dimensionality `N` and the numeric element type `T`. """ abstract AbstractGeometry{N, T} -abstract AbstractMesh{VertT, FaceT} <: AbstractGeometry +abstract AbstractMesh{VertT, FaceT} <: AbstractGeometry{3, Float32} abstract GeometryPrimitive{N, T} <: AbstractGeometry{N, T} diff --git a/src/typeutils.jl b/src/typeutils.jl index c2246e1..db08b70 100644 --- a/src/typeutils.jl +++ b/src/typeutils.jl @@ -1,3 +1,4 @@ +using Compat.TypeUtils """ This is a terrible function. But is there any other way to reliable get the abstract supertype of an arbitrary type hierarchy without loosing performance? From 88db09a0926e0f8986f6cd430a146561bcb5a86e Mon Sep 17 00:00:00 2001 From: CarloLucibello Date: Sat, 1 Apr 2017 14:25:42 +0200 Subject: [PATCH 08/18] drop 0.4 + fixes for 0.6 --- REQUIRE | 5 ++- src/GeometryTypes.jl | 3 +- src/faces.jl | 8 ++-- src/hyperrectangles.jl | 12 +++--- src/hypersphere.jl | 4 +- src/meshes.jl | 20 +++++----- src/polygons.jl | 2 +- src/primitives.jl | 8 ++-- src/simplices.jl | 8 ++-- src/slice.jl | 2 +- src/typealias.jl | 85 +++++++++++++++++++++--------------------- src/types.jl | 22 +++++------ test/runtests.jl | 8 +--- 13 files changed, 92 insertions(+), 95 deletions(-) diff --git a/REQUIRE b/REQUIRE index 260f624..5a55e23 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,5 +1,6 @@ -julia 0.4 +julia 0.5 FixedSizeArrays ColorTypes -Compat 0.7.15 +Compat 0.18 Iterators +FixedPointNumbers diff --git a/src/GeometryTypes.jl b/src/GeometryTypes.jl index cde1d90..7feed41 100644 --- a/src/GeometryTypes.jl +++ b/src/GeometryTypes.jl @@ -4,13 +4,13 @@ module GeometryTypes using FixedSizeArrays using ColorTypes import Iterators +import FixedPointNumbers # U8 import FixedSizeArrays: eltype_or, ndims_or using Compat import Base: ==, *, - call, contains, convert, diff, @@ -168,6 +168,7 @@ export AABB, row, radius, setindex, + slice, spacedim, starts, texturecoordinates, diff --git a/src/faces.jl b/src/faces.jl index 1df7aa9..ba57d8a 100644 --- a/src/faces.jl +++ b/src/faces.jl @@ -26,18 +26,18 @@ convert{T1<:Face}(::Type{T1}, f::T1) = f convert{T1<:Face, T2<:Face}(::Type{T1}, f::T2) = T1(f) # Silly duplication, but call(::FixedVector, ::Any) = convert is overloaded in FixedSizeArrays -@compat (::Type{F}){F<:Face}(f::F) = f +(::Type{F}){F<:Face}(f::F) = f -@compat function (::Type{Face{N, T, O}}){T, T2, O, N}(f::Face{N, T2, O}) +function (::Type{Face{N, T, O}}){T, T2, O, N}(f::Face{N, T2, O}) Face{N, T, O}(convert(NTuple{N, T}, getfield(f, 1))) end immutable IndexConvertFunc{T1, T2} f::T2 end -@compat function (ifunc::IndexConvertFunc{Face{N,T1,O1}, Face{N,T2,O2}}){N,T1,T2,O1,O2}(i) +function (ifunc::IndexConvertFunc{Face{N,T1,O1}, Face{N,T2,O2}}){N,T1,T2,O1,O2}(i) Int(ifunc.f[i])+Int(O1)-Int(O2) end -@compat function (T::Type{Face{N, T1, O1}}){N, T1, O1, F<:Face}(f::F) +function (T::Type{Face{N, T1, O1}}){N, T1, O1, F<:Face}(f::F) map(IndexConvertFunc{T,F}(f), T) end diff --git a/src/hyperrectangles.jl b/src/hyperrectangles.jl index 1880360..b5f1e87 100644 --- a/src/hyperrectangles.jl +++ b/src/hyperrectangles.jl @@ -20,12 +20,12 @@ function _split{H<:HyperRectangle}(b::H, axis, value) end # empty constructor such that update will always include the first point -@compat function (HR::Type{HyperRectangle{N,T}}){T,N}() +function (HR::Type{HyperRectangle{N,T}}){T,N}() HR(Vec{N,T}(typemax(T)), Vec{N,T}(typemin(T))) end # conversion from other HyperRectangles -@compat function (HR::Type{HyperRectangle{N,T1}}){N,T1,T2}(a::HyperRectangle{N,T2}) +function (HR::Type{HyperRectangle{N,T1}}){N,T1,T2}(a::HyperRectangle{N,T2}) HR(Vec{N, T1}(minimum(a)), Vec{N, T1}(widths(a))) end @@ -35,7 +35,7 @@ function HyperRectangle{N,T1,T2}(v1::Vec{N,T1}, v2::Vec{N,T2}) end -@compat function (HR::Type{HyperRectangle{N,T}}){N,T}(a::GeometryPrimitive) +function (HR::Type{HyperRectangle{N,T}}){N,T}(a::GeometryPrimitive) HR(Vec{N, T}(minimum(a)), Vec{N, T}(widths(a))) end """ @@ -63,7 +63,7 @@ function HyperRectangle{T}(r::SimpleRectangle{T}) HyperRectangle{2,T}(r) end -@compat function (::Type{HyperRectangle{N,T}}){N,T}(r::SimpleRectangle) +function (::Type{HyperRectangle{N,T}}){N,T}(r::SimpleRectangle) if N > 2 return HyperRectangle(Vec{N, T}(T(r.x), T(r.y), Vec{N-2,T}(zero(T))...), Vec{N, T}(T(r.w), T(r.h), Vec{N-2,T}(zero(T))...)) @@ -162,7 +162,7 @@ end """ Construct a HyperRectangle enclosing all points. """ -@compat function (t::Type{HyperRectangle{N1, T1}}){N1, T1, PT<:Point}( +function (t::Type{HyperRectangle{N1, T1}}){N1, T1, PT<:Point}( geometry::AbstractArray{PT} ) N2, T2 = length(PT), eltype(PT) @@ -195,7 +195,7 @@ maximum{T}(a::SimpleRectangle{T}) = Point{2, T}(a.x + widths(a)[1], a.y +widths( minimum{T}(a::SimpleRectangle{T}) = Point{2, T}(a.x, a.y) origin{T}(a::SimpleRectangle{T}) = Point{2, T}(a.x, a.y) -@compat (::Type{SimpleRectangle}){T}(val::Vec{2, T}) = SimpleRectangle{T}(0, 0, val...) +(::Type{SimpleRectangle}){T}(val::Vec{2, T}) = SimpleRectangle{T}(0, 0, val...) function SimpleRectangle{T}(position::Vec{2,T}, width::Vec{2,T}) SimpleRectangle{T}(position..., width...) end diff --git a/src/hypersphere.jl b/src/hypersphere.jl index de2c3ca..220fa8b 100644 --- a/src/hypersphere.jl +++ b/src/hypersphere.jl @@ -1,6 +1,6 @@ -@compat (::Type{Sphere})(x...) = HyperSphere(x...) +(::Type{Sphere})(x...) = HyperSphere(x...) -@compat (::Type{Circle})(x...) = HyperSphere(x...) +(::Type{Circle})(x...) = HyperSphere(x...) widths{N, T}(c::HyperSphere{N, T}) = Vec{N, T}(radius(c)*2) radius(c::HyperSphere) = c.r diff --git a/src/meshes.jl b/src/meshes.jl index 918cff7..1d3480a 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -48,7 +48,7 @@ end # Needed to not get into an stack overflow convert{M <: AbstractMesh}(::Type{M}, mesh::AbstractGeometry) = M(mesh) -@compat (::Type{HM1}){HM1 <: AbstractMesh}(mesh::HM1) = mesh +(::Type{HM1}){HM1 <: AbstractMesh}(mesh::HM1) = mesh """ Uses decompose to get all the converted attributes from the meshtype and @@ -57,7 +57,7 @@ Getindex can be defined for any arbitrary geometric type or exotic mesh type. This way, we can make sure, that you can convert most of the meshes from one type to the other with minimal code. """ -@compat function (::Type{HM1}){HM1 <: AbstractMesh}(primitive::Union{AbstractMesh, GeometryPrimitive}) +function (::Type{HM1}){HM1 <: AbstractMesh}(primitive::Union{AbstractMesh, GeometryPrimitive}) result = Dict{Symbol, Any}() for (field, target_type) in zip(fieldnames(HM1), HM1.parameters) if target_type != Void @@ -77,7 +77,7 @@ end isvoid{T}(::Type{T}) = false isvoid(::Type{Void}) = true isvoid{T}(::Type{Vector{T}}) = isvoid(T) -@compat function (::Type{HM1}){HM1 <: HomogenousMesh}(primitive::HomogenousMesh) +function (::Type{HM1}){HM1 <: HomogenousMesh}(primitive::HomogenousMesh) fnames = fieldnames(HM1) args = ntuple(nfields(HM1)) do i field, target_type = fnames[i], fieldtype(HM1, i) @@ -98,7 +98,7 @@ end #Should be: #function call{M <: HMesh, VT <: Point, FT <: Face}(::Type{M}, vertices::Vector{VT}, faces::Vector{FT}) # Haven't gotten around to implement the types correctly with abstract types in FixedSizeArrays -@compat function (::Type{M}){M <: HMesh, VT, FT <: Face}( +function (::Type{M}){M <: HMesh, VT, FT <: Face}( vertices::Vector{Point{3, VT}}, faces::Vector{FT} ) msh = PlainMesh{VT, FT}(vertices=vertices, faces=faces) @@ -122,12 +122,12 @@ end """ Creates a mesh from keyword arguments, which have to match the field types of the given concrete mesh """ -@compat (::Type{M}){M <: HMesh}(; kw_args...) = M(Dict{Symbol, Any}(kw_args)) +(::Type{M}){M <: HMesh}(; kw_args...) = M(Dict{Symbol, Any}(kw_args)) """ Creates a new mesh from a dict of `fieldname => value` and converts the types to the given meshtype """ -@compat function (::Type{M}){M <: HMesh}(attribs::Dict{Symbol, Any}) +function (::Type{M}){M <: HMesh}(attribs::Dict{Symbol, Any}) newfields = map(zip(fieldnames(HomogenousMesh), M.parameters)) do field_target_type field, target_type = field_target_type default = fieldtype(HomogenousMesh, field) <: Vector ? Void[] : nothing @@ -139,7 +139,7 @@ end """ Creates a new mesh from an old one, with changed attributes given by the keyword arguments """ -@compat function (::Type{M}){M <: HMesh}(mesh::AbstractMesh, attributes::Dict{Symbol, Any}) +function (::Type{M}){M <: HMesh}(mesh::AbstractMesh, attributes::Dict{Symbol, Any}) newfields = map(fieldnames(HomogenousMesh)) do field get(attributes, field, getfield(mesh, field)) end @@ -148,7 +148,7 @@ end """ Creates a new mesh from an old one, with a new constant attribute (like a color) """ -@compat function (::Type{HM}){HM <: HMesh, ConstAttrib}(mesh::AbstractMesh, constattrib::ConstAttrib) +function (::Type{HM}){HM <: HMesh, ConstAttrib}(mesh::AbstractMesh, constattrib::ConstAttrib) result = Dict{Symbol, Any}() for (field, target_type) in zip(fieldnames(HM), HM.parameters) if target_type <: ConstAttrib @@ -168,7 +168,7 @@ end """ Creates a new mesh from a tuple of a geometry type and a constant attribute """ -@compat function (::Type{HM}){HM <: HMesh, ConstAttrib, P<:AbstractGeometry}(x::Tuple{P, ConstAttrib}) +function (::Type{HM}){HM <: HMesh, ConstAttrib, P<:AbstractGeometry}(x::Tuple{P, ConstAttrib}) any, const_attribute = x add_attribute(HM(any), const_attribute) end @@ -235,7 +235,7 @@ end immutable MeshMulFunctor{T} matrix::Mat{4,4,T} end -@compat (m::MeshMulFunctor{T}){T}(vert) = Vec{3, T}(m.matrix*Vec{4, T}(vert..., 1)) +(m::MeshMulFunctor{T}){T}(vert) = Vec{3, T}(m.matrix*Vec{4, T}(vert..., 1)) function *{T}(m::Mat{4,4,T}, mesh::AbstractMesh) msh = deepcopy(mesh) map!(MeshMulFunctor(m), msh.vertices) diff --git a/src/polygons.jl b/src/polygons.jl index 5a6be82..6a2565e 100644 --- a/src/polygons.jl +++ b/src/polygons.jl @@ -137,7 +137,7 @@ function topoint{T}(::Type{Point{2, T}}, p::Point{3, T}) Point{2, T}(p[1], p[2]) end -@compat function (::Type{M}){M <: AbstractMesh, P <: Point}( +function (::Type{M}){M <: AbstractMesh, P <: Point}( points::AbstractArray{P} ) faces = polygon2faces(points, facetype(M)) diff --git a/src/primitives.jl b/src/primitives.jl index 6efedfa..bf0483d 100644 --- a/src/primitives.jl +++ b/src/primitives.jl @@ -1,5 +1,5 @@ -@compat function (meshtype::Type{T}){T <: AbstractMesh}(c::Pyramid) +function (meshtype::Type{T}){T <: AbstractMesh}(c::Pyramid) T(decompose(vertextype(T), c), decompose(facetype(T), c)) end @@ -10,7 +10,7 @@ Just walk through all attributes of the mesh and try to decompose it. If there are attributes missing, just hope it will get managed by the mesh constructor. (E.g. normal calculation, which needs to have vertices and faces present) """ -@compat function (meshtype::Type{T}){T <: AbstractMesh}(c::GeometryPrimitive, args...) +function (meshtype::Type{T}){T <: AbstractMesh}(c::GeometryPrimitive, args...) attribs = attributes(T) newattribs = Dict{Symbol, Any}() for (fieldname, typ) in attribs @@ -22,9 +22,9 @@ If there are attributes missing, just hope it will get managed by the mesh const end -@compat function (meshtype::Type{T}){T <: HMesh,HT}( +function (meshtype::Type{T}){T <: HMesh,HT}( c::Union{HyperCube{3,T}, HyperRectangle{3,HT}} - + ) xdir = Vec{3, HT}(widths(c)[1],0f0,0f0) ydir = Vec{3, HT}(0f0,widths(c)[2],0f0) zdir = Vec{3, HT}(0f0,0f0,widths(c)[3]) diff --git a/src/simplices.jl b/src/simplices.jl index be4c2c0..dbb534b 100644 --- a/src/simplices.jl +++ b/src/simplices.jl @@ -2,14 +2,14 @@ # We need this constructor to route around the FixedSizeArray `call` and # so Simplex(Pt, Pt...) etc works. Hopefully these ambiguities will be fixed in # forthcoming Julia versions. -@compat (::Type{S}){S <: Simplex}(s::S) = s -@compat function (::Type{T}){T<:Simplex,F<:FixedVector}(f::F...) +(::Type{S}){S <: Simplex}(s::S) = s +function (::Type{T}){T<:Simplex,F<:FixedVector}(f::F...) Simplex{length(f),F}(f) end -@compat (::Type{S}){S <: Simplex}(fs::FlexibleSimplex) = convert(S, fs) +(::Type{S}){S <: Simplex}(fs::FlexibleSimplex) = convert(S, fs) # FSA doesn't handle symbols for length 1 well. -@compat function (::Type{T}){T<:Simplex}(f::Symbol) +function (::Type{T}){T<:Simplex}(f::Symbol) Simplex{1,Symbol}((f,)) end diff --git a/src/slice.jl b/src/slice.jl index 5401998..05434e2 100644 --- a/src/slice.jl +++ b/src/slice.jl @@ -3,7 +3,7 @@ Slice an AbstractMesh at the specified Z axis value. Returns a Vector of LineSegments generated from the faces at the specified heights. Note: This will not slice in-plane faces. """ -function Base.slice{VT<:AbstractFloat,FT<:Integer,O}(mesh::AbstractMesh{Point{3,VT},Face{3,FT,O}}, height::Number) +function slice{VT<:AbstractFloat,FT<:Integer,O}(mesh::AbstractMesh{Point{3,VT},Face{3,FT,O}}, height::Number) height_ct = length(height) # intialize the LineSegment array diff --git a/src/typealias.jl b/src/typealias.jl index 8bad8e2..ada4b03 100644 --- a/src/typealias.jl +++ b/src/typealias.jl @@ -1,11 +1,11 @@ -#Create typealiases like Mat4f0, Point2, Point2f0 +#Create constes like Mat4f0, Point2, Point2f0 for i=1:4 for T=[:Point, :Vec] name = Symbol("$T$i") namef0 = Symbol("$T$(i)f0") @eval begin - typealias $name $T{$i} - typealias $namef0 $T{$i, Float32} + @compat const $name = $T{$i} + @compat const $namef0 = $T{$i, Float32} export $name export $namef0 end @@ -13,84 +13,85 @@ for i=1:4 name = Symbol("Mat$i") namef0 = Symbol("Mat$(i)f0") @eval begin - typealias $name $Mat{$i,$i} - typealias $namef0 $Mat{$i,$i, Float32} + @compat const $name = $Mat{$i,$i} + @compat const $namef0 = $Mat{$i,$i, Float32} export $name export $namef0 end end #Type aliases +@compat const U8 = FixedPointNumbers.Normed{UInt8, 8} """ An alias for a one-simplex, corresponding to LineSegment{T} -> Simplex{2,T}. """ -typealias LineSegment{T} Simplex{2,T} +@compat const LineSegment{T} = Simplex{2,T} -typealias Triangle{T} Face{3, T, 0} -typealias GLFace{Dim} Face{Dim, Cuint, -1} #offset is relative to julia, so -1 is 0-indexed -typealias GLTriangle Face{3, Cuint, -1} -typealias GLQuad Face{4, Cuint, -1} +@compat const Triangle{T} = Face{3, T, 0} +@compat const GLFace{Dim} = Face{Dim, Cuint, -1} #offset is relative to julia, so -1 is 0-indexed +@compat const GLTriangle = Face{3, Cuint, -1} +@compat const GLQuad = Face{4, Cuint, -1} -typealias Cube{T} HyperCube{3, T} +@compat const Cube{T} = HyperCube{3, T} """ An alias for a HyperSphere of dimension 2. i.e. Circle{T} -> HyperSphere{2, T} """ -typealias Circle{T} HyperSphere{2, T} +@compat const Circle{T} = HyperSphere{2, T} """ An alias for a HyperSphere of dimension 3. i.e. Sphere{T} -> HyperSphere{3, T} """ -typealias Sphere{T} HyperSphere{3, T} +@compat const Sphere{T} = HyperSphere{3, T} -typealias AbsoluteRectangle{T} HyperRectangle{2, T} +@compat const AbsoluteRectangle{T} = HyperRectangle{2, T} """ AABB, or Axis Aligned Bounding Box, is an alias for a 3D HyperRectangle. """ -typealias AABB{T} HyperRectangle{3, T} -@compat (::Type{AABB})(m...) = HyperRectangle(m...) +@compat const AABB{T} = HyperRectangle{3, T} +(::Type{AABB})(m...) = HyperRectangle(m...) -typealias HMesh HomogenousMesh +@compat const HMesh = HomogenousMesh -typealias UV{T} TextureCoordinate{2, T} -typealias UVW{T} TextureCoordinate{3, T} +@compat const UV{T} = TextureCoordinate{2, T} +@compat const UVW{T} = TextureCoordinate{3, T} """ A `SimpleMesh` is an alias for a `HomogenousMesh` parameterized only by vertex and face types. """ -typealias SimpleMesh{VT, FT} HMesh{VT, FT, Void, Void, Void, Void, Void} -typealias PlainMesh{VT, FT} HMesh{Point{3, VT}, FT, Void, Void, Void, Void, Void} -typealias GLPlainMesh PlainMesh{Float32, GLTriangle} +@compat const SimpleMesh{VT, FT} = HMesh{VT, FT, Void, Void, Void, Void, Void} +@compat const PlainMesh{VT, FT} = HMesh{Point{3, VT}, FT, Void, Void, Void, Void, Void} +@compat const GLPlainMesh = PlainMesh{Float32, GLTriangle} -typealias Mesh2D{VT, FT} HMesh{Point{2, VT}, FT, Void, Void, Void, Void, Void} -typealias GLMesh2D Mesh2D{Float32, GLTriangle} +@compat const Mesh2D{VT, FT} = HMesh{Point{2, VT}, FT, Void, Void, Void, Void, Void} +@compat const GLMesh2D = Mesh2D{Float32, GLTriangle} -typealias UVMesh{VT, FT, UVT} HMesh{Point{3, VT}, FT, Void, UV{UVT}, Void, Void, Void} -typealias GLUVMesh UVMesh{Float32, GLTriangle, Float32} +@compat const UVMesh{VT, FT, UVT} = HMesh{Point{3, VT}, FT, Void, UV{UVT}, Void, Void, Void} +@compat const GLUVMesh = UVMesh{Float32, GLTriangle, Float32} -typealias UVWMesh{VT, FT, UVT} HMesh{Point{3, VT}, FT, Void, UVW{UVT}, Void, Void, Void} -typealias GLUVWMesh UVWMesh{Float32, GLTriangle, Float32} +@compat const UVWMesh{VT, FT, UVT} = HMesh{Point{3, VT}, FT, Void, UVW{UVT}, Void, Void, Void} +@compat const GLUVWMesh = UVWMesh{Float32, GLTriangle, Float32} -typealias NormalMesh{VT, FT, NT} HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, Void, Void, Void} -typealias GLNormalMesh NormalMesh{Float32, GLTriangle, Float32} +@compat const NormalMesh{VT, FT, NT} = HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, Void, Void, Void} +@compat const GLNormalMesh = NormalMesh{Float32, GLTriangle, Float32} -typealias UVMesh2D{VT, FT, UVT} HMesh{Point{2, VT}, FT, Void, UV{UVT}, Void, Void, Void} -typealias GLUVMesh2D UVMesh2D{Float32, GLTriangle, Float32} +@compat const UVMesh2D{VT, FT, UVT} = HMesh{Point{2, VT}, FT, Void, UV{UVT}, Void, Void, Void} +@compat const GLUVMesh2D = UVMesh2D{Float32, GLTriangle, Float32} -typealias NormalColorMesh{VT, FT, NT, CT} HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, CT, Void, Void} -typealias GLNormalColorMesh NormalColorMesh{Float32, GLTriangle, Float32, RGBA{Float32}} +@compat const NormalColorMesh{VT, FT, NT, CT} = HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, CT, Void, Void} +@compat const GLNormalColorMesh = NormalColorMesh{Float32, GLTriangle, Float32, RGBA{Float32}} -typealias NormalVertexcolorMesh{VT, FT, NT, CT} HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, Vector{CT}, Void, Void} -typealias GLNormalVertexcolorMesh NormalVertexcolorMesh{Float32, GLTriangle, Float32, RGBA{Float32}} +@compat const NormalVertexcolorMesh{VT, FT, NT, CT} = HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, Vector{CT}, Void, Void} +@compat const GLNormalVertexcolorMesh = NormalVertexcolorMesh{Float32, GLTriangle, Float32, RGBA{Float32}} -typealias NormalAttributeMesh{VT, FT, NT, AT, A_ID_T} HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, Void, AT, A_ID_T} -typealias GLNormalAttributeMesh NormalAttributeMesh{Float32, GLTriangle, Float32, Vector{RGBA{U8}}, Float32} +@compat const NormalAttributeMesh{VT, FT, NT, AT, A_ID_T} = HMesh{Point{3, VT}, FT, Normal{3, NT}, Void, Void, AT, A_ID_T} +@compat const GLNormalAttributeMesh = NormalAttributeMesh{Float32, GLTriangle, Float32, Vector{RGBA{U8}}, Float32} -typealias NormalUVWMesh{VT, FT, NT, UVT} HMesh{Point{3, VT}, FT, Normal{3, NT}, UVW{UVT}, Void, Void, Void} -typealias GLNormalUVWMesh NormalUVWMesh{Float32, GLTriangle, Float32, Float32} +@compat const NormalUVWMesh{VT, FT, NT, UVT} = HMesh{Point{3, VT}, FT, Normal{3, NT}, UVW{UVT}, Void, Void, Void} +@compat const GLNormalUVWMesh = NormalUVWMesh{Float32, GLTriangle, Float32, Float32} -typealias NormalUVMesh{VT, FT, NT, UVT} HMesh{Point{3, VT}, FT, Normal{3, NT}, UV{UVT}, Void, Void, Void} -typealias GLNormalUVMesh NormalUVMesh{Float32, GLTriangle, Float32, Float32} +@compat const NormalUVMesh{VT, FT, NT, UVT} = HMesh{Point{3, VT}, FT, Normal{3, NT}, UV{UVT}, Void, Void, Void} +@compat const GLNormalUVMesh = NormalUVMesh{Float32, GLTriangle, Float32, Float32} diff --git a/src/types.jl b/src/types.jl index 2febb60..b92465a 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1,20 +1,20 @@ -abstract AbstractDistanceField -abstract AbstractUnsignedDistanceField <: AbstractDistanceField -abstract AbstractSignedDistanceField <: AbstractDistanceField +@compat abstract type AbstractDistanceField end +@compat abstract type AbstractUnsignedDistanceField <: AbstractDistanceField end +@compat abstract type AbstractSignedDistanceField <: AbstractDistanceField end """ Abstract to categorize geometry primitives of dimensionality `N` and the numeric element type `T`. """ -abstract AbstractGeometry{N, T} -abstract AbstractMesh{VertT, FaceT} <: AbstractGeometry -abstract GeometryPrimitive{N, T} <: AbstractGeometry{N, T} +@compat abstract type AbstractGeometry{N, T} end +@compat abstract type AbstractMesh{VertT, FaceT} end # <: AbstractGeometry +@compat abstract type GeometryPrimitive{N, T} <: AbstractGeometry{N, T} end """ Abstract to classify Simplices. The convention for N starts at 1, which means a Simplex has 1 point. A 2-simplex has 2 points, and so forth. This convention is not the same as most mathematical texts. """ -abstract AbstractSimplex{N,T} <: FixedVector{N,T} +@compat abstract type AbstractSimplex{N,T} <: FixedVector{N,T} end """ @@ -157,8 +157,8 @@ AbstractFlexibleGeometry{T} AbstractFlexibleGeometry refers to shapes, which are somewhat mutable. """ -abstract AbstractFlexibleGeometry{T} -typealias AFG AbstractFlexibleGeometry +@compat abstract type AbstractFlexibleGeometry{T} end +const AFG = AbstractFlexibleGeometry """ FlexibleConvexHull{T} @@ -184,5 +184,5 @@ AbstractConvexHull Groups all geometry types, that can be described as the convex hull of finitely many points. """ -typealias AbstractConvexHull Union{Simplex, FlexibleConvexHull, FlexibleSimplex, -HyperCube, HyperRectangle} # should we parametrize ACH by the type of points T? +const AbstractConvexHull = Union{Simplex, FlexibleConvexHull, FlexibleSimplex, + HyperCube, HyperRectangle} # should we parametrize ACH by the type of points T? diff --git a/test/runtests.jl b/test/runtests.jl index 4ad24fd..36a6bb0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,10 +1,5 @@ using GeometryTypes, ColorTypes -if VERSION >= v"0.5.0-dev+7720" - using Base.Test -else - using BaseTestNext - const Test = BaseTestNext -end +using Base.Test import Base.Test.@inferred @testset "GeometryTypes" begin @@ -23,4 +18,3 @@ import Base.Test.@inferred include("gjk.jl") include("lines.jl") end - From fd036e844b052c7d25fab4aa551e4be0815b2144 Mon Sep 17 00:00:00 2001 From: CarloLucibello Date: Sat, 1 Apr 2017 19:36:43 +0200 Subject: [PATCH 09/18] import slice for 0.5 --- src/GeometryTypes.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/GeometryTypes.jl b/src/GeometryTypes.jl index 7feed41..2a3ecde 100644 --- a/src/GeometryTypes.jl +++ b/src/GeometryTypes.jl @@ -31,6 +31,10 @@ import Base: ==, union, unique +if VERSION < v"0.6dev" + import Base: slice +end + include("types.jl") include("typeutils.jl") From 423b2f800d378b20c8713b68b215e291b36fa29e Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Apr 2017 12:01:40 +0200 Subject: [PATCH 10/18] fixes for 0.6 --- src/algorithms.jl | 4 +-- src/decompose.jl | 10 +++--- src/deprecated.jl | 16 ---------- src/distancefields.jl | 6 ++-- src/gjk.jl | 7 ++--- src/hyperrectangles.jl | 14 ++++----- src/meshes.jl | 1 + src/operations.jl | 14 ++++++--- src/setops.jl | 12 ++++---- src/simplices.jl | 2 +- src/typealias.jl | 8 ++--- src/typeutils.jl | 43 ++++++-------------------- test/convexhulls.jl | 23 +++++++------- test/distancefields.jl | 10 +++--- test/meshes.jl | 1 + test/simplices.jl | 70 +++++++++++++++++++++--------------------- test/typeutils.jl | 4 +-- 17 files changed, 104 insertions(+), 141 deletions(-) diff --git a/src/algorithms.jl b/src/algorithms.jl index 278e801..9c88d99 100644 --- a/src/algorithms.jl +++ b/src/algorithms.jl @@ -24,8 +24,8 @@ function normals{VT, F <: Face}( normals_result[fi] = normals_result[fi] + n end end - map!(normalize, normals_result) - map(NT, normals_result) + normals_result .= NT.(normalize.(normals_result)) + normals_result end diff --git a/src/decompose.jl b/src/decompose.jl index 72cd64b..4941919 100644 --- a/src/decompose.jl +++ b/src/decompose.jl @@ -5,7 +5,7 @@ primitive. function decompose{SV <: StaticVector, N, T}(::Type{SV}, r::AbstractGeometry{N, T}, args... ) - vectype = similar_type(SV, eltype_or(SV, T), size_or(SV, (N,))) + vectype = similar_type(SV, eltype_or(SV, T), size_or(SV, Size{(N,)}())) # since we have not triangular dispatch, we can't define a function with the # signature for a fully specified Vector type. But we need to check for it # as it means that decompose is not implemented for that version @@ -168,7 +168,7 @@ function decompose{FT1<:Face, FT2<:Face}(::Type{FT1}, faces::Vector{FT2}) N1,N2 = length(FT1), length(FT2) n = length(decompose(FT1, first(faces))) - outfaces = Array(FT1, length(faces)*n) + outfaces = Vector{FT1}(length(faces)*n) i = 1 for face in faces for outface in decompose(FT1, face) @@ -356,7 +356,7 @@ function decompose{T}(PT::Type{Point{2,T}}, s::Circle, n=32) end function decompose{N,T}(PT::Type{Point{N,T}}, s::Sphere, facets=12) - vertices = Array(PT, facets*facets+1) + vertices = Vector{PT}(facets*facets+1) vertices[end] = PT(s.center) - PT(0,0,radius(s)) #Create a vertex for last triangle fan for j=1:facets theta = T((pi*(j-1))/facets) @@ -369,7 +369,7 @@ function decompose{N,T}(PT::Type{Point{N,T}}, s::Sphere, facets=12) vertices end function decompose{FT<:Face}(::Type{FT}, s::Sphere, facets=12) - indexes = Array(FT, facets*facets*2) + indexes = Vector{FT}(facets*facets*2) FTE = eltype(FT) psydo_triangle_i = facets*facets+1 index = 1 @@ -378,7 +378,7 @@ function decompose{FT<:Face}(::Type{FT}, s::Sphere, facets=12) next_index = mod1(i+1, facets) i1 = sub2ind((facets,), j, i) i2 = sub2ind((facets,), j, next_index) - i3 = (j != facets) ? sub2ind((facets,), j+1, i) : psydo_triangle_i + i3 = (j != facets) ? sub2ind((facets,), j+1, i) : psydo_triangle_i i6 = (j != facets) ? sub2ind((facets,), j+1, next_index) : psydo_triangle_i indexes[index] = FT(i1,i2,i3) # convert to required Face index offset indexes[index+1] = FT(i3,i2,i6) diff --git a/src/deprecated.jl b/src/deprecated.jl index 15b3232..e69de29 100644 --- a/src/deprecated.jl +++ b/src/deprecated.jl @@ -1,16 +0,0 @@ -import Base: @deprecate, @deprecate_binding - -@deprecate triangulate{F<:Face}(t::Type{F}, f::Face) decompose(t, f) - - -@deprecate convert{N1, N2, T1, T2}(::Type{HyperRectangle{N1, T1}}, - geometry::Array{Point{N2, T2}}) HyperRectangle{N1,T1}(geometry::Array{Point{N2, T2}}) - -@deprecate_binding Rectangle SimpleRectangle - -# TODO -# These are very tightly coupled to HomogenousMesh. -getindex{PT}(r::SimpleRectangle, t::Type{Point{2, PT}}) = decompose(t, r) -getindex{PT}(p::Pyramid, t::Type{Point{3, PT}}) = decompose(t, p) -getindex{ET}(q::Quad, t::Type{Point{3, ET}}) = decompose(t, q) -decompose{X}(t::Type{X}, m::AbstractMesh) = m[t] diff --git a/src/distancefields.jl b/src/distancefields.jl index e9634b6..69d8171 100644 --- a/src/distancefields.jl +++ b/src/distancefields.jl @@ -16,7 +16,7 @@ may have larger maximum bounds than the input HyperRectangle. The default Field type is Float64, but this can be changed with the `fieldT` argument. """ function SignedDistanceField{T}(f::Function, - bounds::HyperRectangle{3,T}, + bounds::HyperRectangle{3, T}, resolution=0.1, fieldT=Float64) x_min, y_min, z_min = minimum(bounds) @@ -42,7 +42,7 @@ function SignedDistanceField{T}(f::Function, end nb_min = minimum(bounds) - SignedDistanceField{3,T,fieldT}(HyperRectangle(nb_min, nb_max-nb_min), vol) + SignedDistanceField{3,T,fieldT}(HyperRectangle{3, T}(nb_min, nb_max-nb_min), vol) end function SignedDistanceField{T}(f::Function, @@ -69,5 +69,5 @@ function SignedDistanceField{T}(f::Function, end nb_min = minimum(bounds) - SignedDistanceField{2,T,fieldT}(HyperRectangle(nb_min, nb_max-nb_min), vol) + SignedDistanceField{2,T,fieldT}(HyperRectangle{2, T}(nb_min, nb_max-nb_min), vol) end diff --git a/src/gjk.jl b/src/gjk.jl index df03c9f..cf69cd1 100644 --- a/src/gjk.jl +++ b/src/gjk.jl @@ -114,9 +114,9 @@ which has maximal scalar product with v. * pt_best: point inside c realizing dist. """ function gjk0(c, - atol=1e-6, - max_iter=100, - pt_best=any_inside(c) + atol = 1e-6, + max_iter = 100, + pt_best = any_inside(c) ) @assert atol >= 0 @@ -125,7 +125,6 @@ function gjk0(c, sim = FlexibleSimplex(T[]) for k in 1:max_iter direction = -pt_best - wk, score = support_vector_max(c, direction) if (score <= (pt_best ⋅ direction) + atol) # pt_best is already most extreme return pt_best, norm(pt_best) diff --git a/src/hyperrectangles.jl b/src/hyperrectangles.jl index 4b6e9e0..e0ae41f 100644 --- a/src/hyperrectangles.jl +++ b/src/hyperrectangles.jl @@ -7,8 +7,8 @@ widths(prim::HyperRectangle) = prim.widths """ Splits an HyperRectangle into two along an axis at a given location. """ -split{H<:HyperRectangle}(b::H, axis, value::Integer) = _split(b,axis,value) -split{H<:HyperRectangle}(b::H, axis, value::Number) = _split(b,axis,value) +split(b::HyperRectangle, axis, value::Integer) = _split(b, axis, value) +split(b::HyperRectangle, axis, value::Number) = _split(b, axis, value) function _split{H<:HyperRectangle}(b::H, axis, value) bmin = minimum(b) bmax = maximum(b) @@ -86,10 +86,10 @@ function *{N1,N2,T1,T2}(m::Mat{N1,N1,T1}, h::HyperRectangle{N2, T2}) # get all points on the HyperRectangle d = decompose(Point, h) # make sure our points are sized for the tranform - pts = (Vec{N1,T}[vcat(pt, ones(Vec{D,T})) for pt in d]...)::NTuple{2^N2,Vec{N1,T}} + pts = (Vec{N1, T}[vcat(pt, ones(Vec{D, T})) for pt in d]...)::NTuple{2^N2,Vec{N1,T}} - vmin = Vec{D, T}(typemax(T)) - vmax = Vec{D, T}(typemin(T)) + vmin = Vec{N1, T}(typemax(T)) + vmax = Vec{N1, T}(typemin(T)) # tranform all points, tracking min and max points for pt in pts pn = m * pt @@ -115,8 +115,8 @@ function *{N,T1,T2}(m::Mat{N,N,T1}, h::HyperRectangle{N,T2}) # tranform all points, tracking min and max points for pt in pts pn = m * Vec(pt) - vmin = min(pn,vmin) - vmax = max(pn,vmax) + vmin = min.(pn, vmin) + vmax = max.(pn, vmax) end HyperRectangle{N,T}(vmin, vmax-vmin) end diff --git a/src/meshes.jl b/src/meshes.jl index 69cba12..a16d436 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -48,6 +48,7 @@ end # Needed to not get into an stack overflow convert{M <: AbstractMesh}(::Type{M}, mesh::AbstractGeometry) = M(mesh) +convert(::Type{T}, mesh::T) where T <: AbstractMesh = mesh #@compat (::Type{HM1}){HM1 <: AbstractMesh}(mesh::HM1) = mesh """ diff --git a/src/operations.jl b/src/operations.jl index 8d3d96d..2453a5b 100644 --- a/src/operations.jl +++ b/src/operations.jl @@ -2,7 +2,7 @@ function update{N, T, T2}(b::HyperRectangle{N, T}, v::Vec{N, T2}) update(b, Vec{N, T}(v)) end function update{N, T}(b::HyperRectangle{N, T}, v::Vec{N, T}) - m = min(minimum(b), v) + m = min.(minimum(b), v) maxi = maximum(b) mm = if isnan(maxi) v-m @@ -24,15 +24,19 @@ end @inline function min_dist_dim{N, T}(rect1::HyperRectangle{N, T}, rect2::HyperRectangle{N, T}, dim::Int) - max(zero(T), max(minimum(rect1)[dim] - maximum(rect2)[dim], - minimum(rect2)[dim] - maximum(rect1)[dim])) + max(zero(T), max( + minimum(rect1)[dim] - maximum(rect2)[dim], + minimum(rect2)[dim] - maximum(rect1)[dim] + )) end @inline function max_dist_dim{N, T}(rect1::HyperRectangle{N, T}, rect2::HyperRectangle{N, T}, dim::Int) - max(maximum(rect1)[dim] - minimum(rect2)[dim], - maximum(rect2)[dim] - minimum(rect1)[dim]) + max( + maximum(rect1)[dim] - minimum(rect2)[dim], + maximum(rect2)[dim] - minimum(rect1)[dim] + ) end # Total minimum maximum distance functions diff --git a/src/setops.jl b/src/setops.jl index 14192a2..84bfb07 100644 --- a/src/setops.jl +++ b/src/setops.jl @@ -2,8 +2,8 @@ Perform a union between two HyperRectangles. """ function union{T,N}(h1::HyperRectangle{N, T}, h2::HyperRectangle{N, T}) - m = min(minimum(h1), minimum(h2)) - mm = max(maximum(h1), maximum(h2)) + m = min.(minimum(h1), minimum(h2)) + mm = max.(maximum(h1), maximum(h2)) HyperRectangle{N, T}(m, mm-m) end @@ -18,14 +18,14 @@ diff(h1::HyperRectangle, h2::HyperRectangle) = h1 Perform a intersection between two HyperRectangles. """ function intersect{T,N}(h1::HyperRectangle{N, T}, h2::HyperRectangle{N, T}) - m = max(minimum(h1), minimum(h2)) - mm = min(maximum(h1), maximum(h2)) + m = max.(minimum(h1), minimum(h2)) + mm = min.(maximum(h1), maximum(h2)) HyperRectangle{N, T}(m, mm-m) end function intersect(a::SimpleRectangle, b::SimpleRectangle) - min_n = max(minimum(a), minimum(b)) - max_n = min(maximum(a), maximum(b)) + min_n = max.(minimum(a), minimum(b)) + max_n = min.(maximum(a), maximum(b)) w = max_n - min_n SimpleRectangle(min_n[1], min_n[2], w[1], w[2]) end diff --git a/src/simplices.jl b/src/simplices.jl index f9fa519..2ad9ee6 100644 --- a/src/simplices.jl +++ b/src/simplices.jl @@ -23,7 +23,7 @@ end Base.@pure Base.size{S}(::Union{Simplex{S}, Type{Simplex{S}}}) = (S, ) Base.@pure Base.size{S,T}(::Type{Simplex{S, T}}) = (S,) -Base.@propagate_inbounds function Base.getindex(v::Simplex, i::Integer) +Base.@propagate_inbounds function Base.getindex(v::Simplex, i::Int) v.data[i] end @inline Base.Tuple(v::Simplex) = v.data diff --git a/src/typealias.jl b/src/typealias.jl index b3710dd..36c95d0 100644 --- a/src/typealias.jl +++ b/src/typealias.jl @@ -4,8 +4,8 @@ for i=1:4 name = Symbol("$T$i") namef0 = Symbol("$T$(i)f0") @eval begin - typealias $name $T{$i} - typealias $namef0 $T{$i, Float32} + const $name = $T{$i} + const $namef0 = $T{$i, Float32} export $name export $namef0 end @@ -13,8 +13,8 @@ for i=1:4 name = Symbol("Mat$i") namef0 = Symbol("Mat$(i)f0") @eval begin - typealias $name{T} $Mat{$i,$i, T, $(i*i)} - typealias $namef0 $name{Float32} + @compat const $name{T} = $Mat{$i,$i, T, $(i*i)} + const $namef0 = $name{Float32} export $name export $namef0 end diff --git a/src/typeutils.jl b/src/typeutils.jl index db08b70..f94193b 100644 --- a/src/typeutils.jl +++ b/src/typeutils.jl @@ -1,40 +1,15 @@ using Compat.TypeUtils -""" -This is a terrible function. But is there any other way to reliable get the -abstract supertype of an arbitrary type hierarchy without loosing performance? -""" -@generated function go_abstract{T<:AbstractGeometry}(::Type{T}) - ff = T - while ff.name.name != :AbstractGeometry - ff = supertype(ff) - end - :($ff) -end -@generated function eltype_or{T<:GeometryPrimitive}(::Type{T}, OR) - ET = go_abstract(T).parameters[2] - if isa(ET, TypeVar) - return :(OR) - else - return :($ET) - end -end -@generated function ndims_or{T<:GeometryPrimitive}(::Type{T}, OR) - N = go_abstract(T).parameters[1] - if isa(N, TypeVar) - return :(OR) - else - return :($N) - end -end +eltype_or(::Type{<: AbstractGeometry{N, T} where N}, or) where T = T +eltype_or(::Type{<: AbstractGeometry{N, T} where N where T}, or) = or -function Base.eltype{T<:AbstractGeometry}(x::Type{T}) - eltype_or(T, Any) -end -@generated function Base.ndims{T<:AbstractGeometry}(x::Type{T}) - N = go_abstract(T).parameters[1] - isa(N, TypeVar) && error("Ndims not given for type $T") - :($N) +ndims_or(::Type{<: AbstractGeometry{N, T} where T}, or) where N = N +ndims_or(::Type{<: AbstractGeometry{N, T} where N where T}, or) = or + +Base.eltype(T::Type{<:AbstractGeometry}) = eltype_or(T, Any) + +function Base.ndims(T::Type{<:AbstractGeometry}) + ndims_or(T, Any) end Base.eltype{N, T}(x::AbstractGeometry{N, T}) = T diff --git a/test/convexhulls.jl b/test/convexhulls.jl index 8a84112..fc3ca5f 100644 --- a/test/convexhulls.jl +++ b/test/convexhulls.jl @@ -2,9 +2,9 @@ import GeometryTypes: numtype @testset "Convex Hulls" begin T = Float64 V = Vec{2, T} - s = Simplex((Vec(0, 0.), Vec(0,1.), Vec(1.,0))) - fs = FlexibleSimplex([Vec(0.0,0.0), Vec(0.0,1.0), Vec(1.0,0.0)]) - fh = FlexibleConvexHull([Vec(0.0,0.0), Vec(0.0,1.0), Vec(1.0,0.0)]) + s = Simplex((Vec(0.0, 0.), Vec(0.0, 1.0), Vec(1.0, 0.0))) + fs = FlexibleSimplex([Vec(0.0, 0.0), Vec(0.0, 1.0), Vec(1.0, 0.0)]) + fh = FlexibleConvexHull([Vec(0.0, 0.0), Vec(0.0, 1.0), Vec(1.0, 0.0)]) types = (Simplex, FlexibleSimplex, FlexibleConvexHull) objects = (s,fs,fh) @@ -19,7 +19,7 @@ import GeometryTypes: numtype @testset "Utility functions" begin - v_matrix = [0. 0 1; 0 1 0] + v_matrix = [0.0 0.0 1.0; 0.0 1.0 0.0] v_mat = Mat{2, 3}(v_matrix) for shape in objects @test (@inferred eltype(shape)) == V @@ -35,18 +35,17 @@ import GeometryTypes: numtype end @testset "isapprox" begin - s2 = rand(Simplex{3, Vec{2,Float64}}) + s2 = rand(Simplex{3, Vec{2, Float64}}) - @test !( isapprox(s, s2) ) - @test isapprox(s, s2, atol=100.) + @test !isapprox(s, s2) + @test isapprox(s, s2, atol = 100.0) end @testset "Rects" begin - c = HyperCube(Vec(1.,2), 1.) - r = HyperRectangle(Vec(1.,2), Vec(1.,1)) - fh = FlexibleConvexHull([ Vec(1,2.), Vec(1.,3.), Vec(2.,2.), Vec(2.,3.)]) - objects = (c,r,fh) - + c = HyperCube(Vec(1.0, 2.0), 1.0) + r = HyperRectangle(Vec(1.0, 2.0), Vec(1.0, 1.0)) + fh = FlexibleConvexHull(Vec{2, Float64}[(1.0, 2.0), (1.0, 3.0), (2.0,2.0), (2.0,3.0)]) + objects = (c, r, fh) @test (@inferred convert(HyperRectangle, c)) == r fh2 = (@inferred convert(FlexibleConvexHull, c)) @test vertices(fh2) == vertices(fh) diff --git a/test/distancefields.jl b/test/distancefields.jl index 2fbc554..b029d15 100644 --- a/test/distancefields.jl +++ b/test/distancefields.jl @@ -8,23 +8,23 @@ # functional - s2 = SignedDistanceField(HyperRectangle(Vec(0,0,0.),Vec(1,1,1.))) do v + s2 = SignedDistanceField(HyperRectangle(Vec(0,0,0),Vec(1,1,1))) do v sqrt(sum(v.*v)) - 1 # sphere end @test size(s2) == (11, 11, 11) # functional - s2 = SignedDistanceField(HyperRectangle(Vec(-1,-1.),Vec(2,3.))) do v + s2 = SignedDistanceField(HyperRectangle(Vec(-1,-1),Vec(2,3))) do v sqrt(sum(v.*v)) - 1 # circle end @test size(s2) == (21, 31) @test size(s2, 1) == 21 @test size(s2, 2) == 31 - @test HyperRectangle(s2) == HyperRectangle(Vec(-1,-1.),Vec(2,3.)) + @test HyperRectangle(s2) == HyperRectangle(Vec(-1,-1),Vec(2,3)) end @testset "getindex" begin - sdf = SignedDistanceField(HyperRectangle(Vec(-1,-1.),Vec(2,2.))) do v + sdf = SignedDistanceField(HyperRectangle(Vec(-1,-1),Vec(2,2))) do v sqrt(sum(v.*v)) - 1 # circle end @@ -32,4 +32,4 @@ end @test_throws BoundsError sdf[21*21+1] end -end \ No newline at end of file +end diff --git a/test/meshes.jl b/test/meshes.jl index 3d2d364..848d0e1 100644 --- a/test/meshes.jl +++ b/test/meshes.jl @@ -1,3 +1,4 @@ +using GeometryTypes: slice @testset "Mesh Types" begin @testset "Merging Mesh" begin diff --git a/test/simplices.jl b/test/simplices.jl index 6ed2afa..a9eeb6e 100644 --- a/test/simplices.jl +++ b/test/simplices.jl @@ -1,19 +1,19 @@ @testset "example simplices" begin @testset "2d simplex in 2d" begin - s = Simplex((Vec(1,0.), Vec(0,1.), Vec(0,0.))) - @test (@inferred min_euclidean(Vec(0., 0.), s)) ≈0 - @test min_euclidean(Vec(0.5, 0.),s) ≈0 - @test min_euclidean(Vec(-1, -1.),s) ≈√(2) - @test min_euclidean(Vec(-7, 0.5),s) ≈7 - @test min_euclidean(Vec(1., 1.), s) ≈√(0.5) + s = Simplex((Vec(1.0,0.0), Vec(0.0,1.0), Vec(0.0,0.0))) + @test (@inferred min_euclidean(Vec(0.0, 0.0), s)) ≈0 + @test min_euclidean(Vec(0.5, 0.0),s) ≈0 + @test min_euclidean(Vec(-1.0, -1.0),s) ≈√(2) + @test min_euclidean(Vec(-7.0, 0.5),s) ≈7 + @test min_euclidean(Vec(1.0, 1.0), s) ≈√(0.5) @test (@inferred volume(s)) ≈1/2 # containment - @test contains(s, Vec(0.1, 0.)) + @test contains(s, Vec(0.1, 0.0)) for v in vertices(s) @test contains(s, v) end - @test !( contains(s, Vec(1,0.1)) ) - @test contains(s, Vec(1,0.1), atol=0.1) + @test !( contains(s, Vec(1.0,0.1)) ) + @test contains(s, Vec(1.0,0.1), atol = 0.1) end @testset "counterexample" begin @@ -22,49 +22,49 @@ # https://www.researchgate.net/publication/267801141_-_An_Algorithm_to_Compute_the_Distance_from_a_Point_to_a_Simplex # Here is a counterexample - s = Simplex((Vec(-1,0.), Vec(0,0.), Vec(1,1.))) - pt = Vec(2.,-1) + s = Simplex((Vec(-1.0,0.), Vec(0.0,0.), Vec(1.0,1.))) + pt = Vec(2.,-1.0) @test min_euclidean(pt, s) ≈√(4.5) pt_proj, sqd = GeometryTypes.proj_sqdist(pt, s) @test pt_proj ≈ Vec(0.5, 0.5) - @test !isapprox(pt_proj, Vec(0,0.), atol=1e-1) + @test !isapprox(pt_proj, Vec(0.0,0.), atol=1e-1) @test sqd ≈4.5 end @testset "3d simplex in 3d" begin - s = Simplex((Vec(1,0.,0), Vec(0,1.,0), Vec(0,0,1.), Vec(0,0.,0))) + s = Simplex((Vec(1.0,0.0,0.0), Vec(0.0,1.0,0.0), Vec(0.0,0.0,1.0), Vec(0.0,0.0,0.0))) #@test (@inferred min_euclidean(Vec(0., 0.,0), s)) ≈ 0 - @test min_euclidean(Vec(0., 0.,0), s) ≈ 0 - @test min_euclidean(Vec(0.5, 0.,0),s) ≈ 0 - @test min_euclidean(Vec(-1, -1.,0),s) ≈ √(2) - @test min_euclidean(Vec(-7, 0.5,0),s) ≈ 7 - @test min_euclidean(Vec(1., 1.,0), s) ≈ √(0.5) - @test min_euclidean(Vec(1., 1.,1), s) ≈ √(3)*(2/3) - @test (@inferred volume(s)) ≈1/6 - @test !( contains(s, Vec(1,0,0.1)) ) - @test contains(s, Vec(0.1,0,0.1)) + @test min_euclidean(Vec(0.0, 0.0, 0.0), s) ≈ 0 + @test min_euclidean(Vec(0.5, 0.0, 0.0),s) ≈ 0 + @test min_euclidean(Vec(-1.0, -1.0, 0.0),s) ≈ √(2) + @test min_euclidean(Vec(-7.0, 0.5, 0.0),s) ≈ 7 + @test min_euclidean(Vec(1.0, 1.0, 0.0), s) ≈ √(0.5) + @test min_euclidean(Vec(1.0, 1.0, 1.0), s) ≈ √(3)*(2/3) + @test (@inferred volume(s)) ≈ 1/6 + @test !( contains(s, Vec(1.0, 0.0, 0.1)) ) + @test contains(s, Vec(0.1, 0.0, 0.1)) end @testset "1d simplex in 2d" begin - s = Simplex((Vec(-1, 1.), Vec(1,1.))) + s = Simplex((Vec(-1.0, 1.), Vec(1.0, 1.))) proj(pt) = GeometryTypes.proj_sqdist(pt, s)[1] - @test proj(Vec( 0., 2)) ≈ Vec( 0, 1.) - @test proj(Vec( 0., -2)) ≈ Vec( 0, 1.) - @test proj(Vec( 56., 2)) ≈ Vec( 1, 1.) - @test proj(Vec(-56., 2)) ≈ Vec(-1, 1.) + @test proj(Vec(0.0, 2.0)) ≈ Vec(0.0, 1.0) + @test proj(Vec(0.0, -2.0)) ≈ Vec(0.0, 1.0) + @test proj(Vec(56.0, 2.0)) ≈ Vec(1.0, 1.0) + @test proj(Vec(-56.0, 2.0)) ≈ Vec(-1.0, 1.0) end @testset "1d simplex in 3d" begin - s = Simplex((Vec(0,0.,0), Vec(1,1.,1))) - @test (@inferred min_euclidean(Vec(0., 0.,0), s)) ≈0 - @test min_euclidean(Vec(.5, .5, .5), s) ≈0 - @test min_euclidean(Vec(-1,0,0.), s) ≈1 - @test min_euclidean(Vec(1,0,0.), s) ≈√(2/3) - @test (@inferred volume(s)) ≈√(3) + s = Simplex((Vec(0.0, 0.0, 0.0), Vec(1.0, 1.0, 1.0))) + @test (@inferred min_euclidean(Vec(0.0, 0.0, 0.0), s)) ≈ 0 + @test min_euclidean(Vec(0.5, 0.5, 0.5), s) ≈ 0 + @test min_euclidean(Vec(-1.0, 0.0, 0.0), s) ≈ 1 + @test min_euclidean(Vec(1.0, 0.0, 0.0), s) ≈ √(2/3) + @test (@inferred volume(s)) ≈ √(3) - @test contains(s, Vec(0.2,0.2,0.2)) - @test !( contains(s, Vec(0.1,0.0999,0.1)) ) + @test contains(s, Vec(0.2, 0.2, 0.2)) + @test !(contains(s, Vec(0.1, 0.0999, 0.1))) end end diff --git a/test/typeutils.jl b/test/typeutils.jl index b3f74b1..7b09ed2 100644 --- a/test/typeutils.jl +++ b/test/typeutils.jl @@ -21,5 +21,5 @@ end @test ndims(SimpleRectangle) == 2 @test ndims(HyperCube{2}) == 2 @test ndims(HyperCube{2, Float32}) == 2 - @test_throws Exception ndims(HyperCube) -end \ No newline at end of file + #@test_throws Exception ndims(HyperCube) +end From e9f5f919da0a45a3a0d90f06f685cbbcf0fc64da Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Apr 2017 14:13:24 +0200 Subject: [PATCH 11/18] fix remaining issues --- src/lines.jl | 2 +- src/operations.jl | 2 +- src/simplices.jl | 2 +- src/types.jl | 12 ++++-------- test/runtests.jl | 6 ++++-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/lines.jl b/src/lines.jl index 9eaa47e..a9496c7 100644 --- a/src/lines.jl +++ b/src/lines.jl @@ -48,7 +48,7 @@ end function simple_concat{P}(vec, range, endpoint::P) - result = Array(P, length(range)+1) + result = Vector{P}(length(range)+1) for (i,j) in enumerate(range) result[i] = vec[mod1(j, length(vec))] end diff --git a/src/operations.jl b/src/operations.jl index 2453a5b..eb79a14 100644 --- a/src/operations.jl +++ b/src/operations.jl @@ -7,7 +7,7 @@ function update{N, T}(b::HyperRectangle{N, T}, v::Vec{N, T}) mm = if isnan(maxi) v-m else - max(v, maxi) - m + max.(v, maxi) - m end HyperRectangle{N, T}(m, mm) end diff --git a/src/simplices.jl b/src/simplices.jl index 2ad9ee6..69f7551 100644 --- a/src/simplices.jl +++ b/src/simplices.jl @@ -39,7 +39,7 @@ end # function StaticArrays.similar_type{SV <: Simplex}(::Union{SV, Type{SV}}, s::Tuple{Int}) # Simplex{s[1], eltype(SV)} # end -function StaticArrays.similar_type{SV <: Simplex, T}(::Union{Simplex, Type{Simplex}}, ::Type{T}, s::Tuple{Int}) +function StaticArrays.similar_type{T}(::Union{Simplex, Type{Simplex}}, ::Type{T}, s::Tuple{Int}) Simplex{s[1], T} end diff --git a/src/types.jl b/src/types.jl index cb1c3d8..d30bad6 100644 --- a/src/types.jl +++ b/src/types.jl @@ -42,12 +42,8 @@ to allow embedding in higher-order spaces by parameterizing on `T`. """ immutable Simplex{S, T} <: AbstractSimplex{T} data::NTuple{S, T} - function Simplex(x::NTuple{S, T}) - new(x) - end - function Simplex(x::NTuple{S}) - new(StaticArrays.convert_ntuple(T, x)) - end + (::Type{Simplex{S, T}}){S, T}(x::NTuple{S, T}) = new{S, T}(x) + (::Type{Simplex{S, T}}){S, T}(x::NTuple{S}) = new{S, T}(StaticArrays.convert_ntuple(T, x)) end @fixed_vector Vec StaticVector @@ -78,8 +74,8 @@ communicating with 0-indexed systems such ad OpenGL. """ immutable OffsetInteger{O, T <: Integer} <: Integer i::T - function OffsetInteger(x::T) - new(x - O) + function (::Type{OffsetInteger{O, T}}){O, T}(x::T) + new{O, T}(x - O) end end diff --git a/test/runtests.jl b/test/runtests.jl index 0ffc9ff..7b2b06c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,8 @@ using GeometryTypes, ColorTypes using Base.Test import Base.Test.@inferred +# StaticArrays needs to get tagged first! +Pkg.checkout("StaticArrays", "sd/fixedsizearrays") @testset "GeometryTypes" begin include("polygons.jl") @@ -15,8 +17,8 @@ import Base.Test.@inferred include("hypersphere.jl") include("typeutils.jl") include("simplices.jl") - include("convexhulls.jl") - include("gjk.jl") include("lines.jl") include("polygons.jl") + #include("convexhulls.jl") + #include("gjk.jl") end From f5520ba2261fa7876b244a1da8a67ca1ddc546a3 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Apr 2017 15:12:01 +0200 Subject: [PATCH 12/18] drop 0.5/0.4 for real! --- .travis.yml | 12 +----------- REQUIRE | 4 ++-- appveyor.yml | 18 ++++++------------ 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index a0b28d4..f5a35c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,18 +3,8 @@ os: - linux - osx julia: - - 0.4 - - 0.5 + - 0.6 - nightly -matrix: - allow_failures: - - julia: nightly - notifications: email: false sudo: false -script: - - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi - - julia --inline=no -e 'Pkg.clone(pwd()); Pkg.build("GeometryTypes"); Pkg.test("GeometryTypes"; coverage=true)' -after_success: - - julia -e 'cd(Pkg.dir("GeometryTypes")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder()); Codecov.submit(process_folder())' diff --git a/REQUIRE b/REQUIRE index 5a55e23..51b9ce2 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,5 +1,5 @@ -julia 0.5 -FixedSizeArrays +julia 0.6 +StaticArrays ColorTypes Compat 0.18 Iterators diff --git a/appveyor.yml b/appveyor.yml index aa4a5c1..d3eaaa2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,14 +1,12 @@ environment: matrix: - - JULIAVERSION: "julialang/bin/winnt/x86/0.4/julia-0.4-latest-win32.exe" - - JULIAVERSION: "julialang/bin/winnt/x64/0.4/julia-0.4-latest-win64.exe" - - JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe" - - JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe" + - JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe" + - JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe" branches: only: - master - - /release-.*/ +# - /release-.*/ notifications: - provider: Email @@ -17,11 +15,6 @@ notifications: on_build_status_changed: false install: -# If there's a newer build queued for the same PR, cancel this one - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` - https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` - Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` - throw "There are newer queued builds for this pull request, failing early." } # Download most recent Julia Windows binary - ps: (new-object net.webclient).DownloadFile( $("http://s3.amazonaws.com/"+$env:JULIAVERSION), @@ -32,7 +25,8 @@ install: build_script: # Need to convert from shallow to complete for Pkg.clone to work - IF EXIST .git\shallow (git fetch --unshallow) - - C:\projects\julia\bin\julia -e "versioninfo(); Pkg.clone(pwd(), \"GeometryTypes\")" + - C:\projects\julia\bin\julia -e "versioninfo(); + Pkg.clone(pwd(), \"GeometryTypes\"); Pkg.build(\"GeometryTypes\")" test_script: - - C:\projects\julia\bin\julia -e "Pkg.test(\"GeometryTypes\")" + - C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"GeometryTypes\")" From 5e6aaf32a383c38d4e8fd004804b88c7ea4dd56b Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Apr 2017 15:29:59 +0200 Subject: [PATCH 13/18] drop 0.5 for StaticArrays --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 51b9ce2..13fb67c 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,4 @@ -julia 0.6 +julia 0.6- StaticArrays ColorTypes Compat 0.18 From d64f6b2ccec0463ecbd920f9eee007d54fe2f49d Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Apr 2017 15:31:38 +0200 Subject: [PATCH 14/18] checkout before using --- test/runtests.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 7b2b06c..04c594b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,10 @@ +# StaticArrays needs to get tagged first! +Pkg.checkout("StaticArrays", "sd/fixedsizearrays") + using GeometryTypes, ColorTypes using Base.Test import Base.Test.@inferred -# StaticArrays needs to get tagged first! -Pkg.checkout("StaticArrays", "sd/fixedsizearrays") @testset "GeometryTypes" begin include("polygons.jl") From e34a220a54ac90a429bdd40814d9c19799140dd9 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 6 Apr 2017 21:41:32 +0200 Subject: [PATCH 15/18] fixes for 0.6 --- src/faces.jl | 5 ++++- src/meshes.jl | 18 ++++++++---------- src/types.jl | 6 ++++-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/faces.jl b/src/faces.jl index 866af41..e31279b 100644 --- a/src/faces.jl +++ b/src/faces.jl @@ -1,4 +1,7 @@ -import Base: +, -, abs, *, /, div, convert, ==, <=, >=, show +import Base: +, -, abs, *, /, div, convert, ==, <=, >=, show, to_index + + +to_index(I::AbstractArray{<:Face}) = I function show{O, T}(io::IO, oi::OffsetInteger{O, T}) i = T(oi) diff --git a/src/meshes.jl b/src/meshes.jl index 19c81e8..4ad720d 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -1,8 +1,8 @@ -for s in enumerate((:vertextype, :facetype, :normaltype, +for (i, field) in enumerate((:vertextype, :facetype, :normaltype, :texturecoordinatetype, :colortype)) @eval begin - $(s[2]){T<:HomogenousMesh}(t::Type{T}) = t.parameters[$(s[1])] - $(s[2])(mesh::HomogenousMesh) = $(s[2])(typeof(mesh)) + $field{T <: HomogenousMesh}(t::Type{T}) = eltype(fieldtype(t, $i)) + $field(mesh::HomogenousMesh) = $field(typeof(mesh)) end end @@ -12,8 +12,6 @@ hasnormals(msh) = normaltype(msh) != Void hastexturecoordinates(msh) = texturecoordinatetype(msh) != Void hascolors(msh) = colortype(msh) != Void - - vertices(msh) = msh.vertices faces(msh) = msh.faces normals(msh) = msh.normals @@ -22,7 +20,7 @@ colors(msh) = msh.color # Bad, bad name! But it's a little tricky to filter out faces and verts from the attributes, after get_attribute -function attributes_noVF{T<:AbstractMesh}(m::T) +function attributes_noVF{T <: AbstractMesh}(m::T) fielddict = Dict{Symbol, Any}(map(fieldnames(T)[3:end]) do field field => getfield(m, field) end) @@ -83,7 +81,7 @@ function (::Type{HM1}){HM1 <: HomogenousMesh}(primitive::HomogenousMesh) args = ntuple(nfields(HM1)) do i field, target_type = fnames[i], fieldtype(HM1, i) soure_type = fieldtype(typeof(primitive), i) - isa(HM1.parameters[i], TypeVar) && return getfield(primitive, field) # target is not defined + isleaftype(fieldtype(HM1, i)) || return getfield(primitive, field) # target is not defined if !isvoid(target_type) && isvoid(soure_type) # target not there yet, maybe we can decompose though (e.g. normals) return decompose(HM1.parameters[i], primitive) elseif isvoid(target_type) @@ -102,7 +100,7 @@ end function (::Type{M}){M <: HMesh, VT, FT <: Face}( vertices::Vector{Point{3, VT}}, faces::Vector{FT} ) - msh = PlainMesh{VT, FT}(vertices=vertices, faces=faces) + msh = PlainMesh{VT, FT}(vertices = vertices, faces = faces) convert(M, msh) end get_default(x::Union{Type, TypeVar}) = nothing @@ -129,8 +127,8 @@ Creates a mesh from keyword arguments, which have to match the field types of th Creates a new mesh from a dict of `fieldname => value` and converts the types to the given meshtype """ function (::Type{M}){M <: HMesh}(attribs::Dict{Symbol, Any}) - newfields = map(zip(fieldnames(HomogenousMesh), M.parameters)) do field_target_type - field, target_type = field_target_type + newfields = map(fieldnames(HomogenousMesh)) do field + target_type = fieldtype(M, field) default = fieldtype(HomogenousMesh, field) <: Vector ? Void[] : nothing get(attribs, field, default) end diff --git a/src/types.jl b/src/types.jl index d30bad6..4be65e4 100644 --- a/src/types.jl +++ b/src/types.jl @@ -209,5 +209,7 @@ AbstractConvexHull Groups all geometry types, that can be described as the convex hull of finitely many points. """ -const AbstractConvexHull = Union{Simplex, FlexibleConvexHull, FlexibleSimplex, - HyperCube, HyperRectangle} # should we parametrize ACH by the type of points T? +const AbstractConvexHull = Union{ + Simplex, FlexibleConvexHull, FlexibleSimplex, + HyperCube, HyperRectangle +} # should we parametrize ACH by the type of points T? From 407b212fd370f208ba2489e4d91ae2f7eba68bba Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Wed, 19 Apr 2017 15:04:52 +0200 Subject: [PATCH 16/18] fix tests --- src/meshes.jl | 5 ++++- src/types.jl | 4 ++-- test/meshes.jl | 22 ++++++++++++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/meshes.jl b/src/meshes.jl index 4ad720d..d0177dc 100644 --- a/src/meshes.jl +++ b/src/meshes.jl @@ -1,7 +1,10 @@ + +_eltype{T <: AbstractArray}(::Type{T}) = eltype(T) +_eltype{T}(::Type{T}) = T for (i, field) in enumerate((:vertextype, :facetype, :normaltype, :texturecoordinatetype, :colortype)) @eval begin - $field{T <: HomogenousMesh}(t::Type{T}) = eltype(fieldtype(t, $i)) + $field{T <: HomogenousMesh}(t::Type{T}) = _eltype(fieldtype(t, $i)) $field(mesh::HomogenousMesh) = $field(typeof(mesh)) end end diff --git a/src/types.jl b/src/types.jl index 4be65e4..4a9662c 100644 --- a/src/types.jl +++ b/src/types.jl @@ -21,7 +21,7 @@ Abstract to classify Simplices. The convention for N starts at 1, which means a Simplex has 1 point. A 2-simplex has 2 points, and so forth. This convention is not the same as most mathematical texts. """ -@compat abstract type AbstractSimplex{T} <: StaticVector{T} end +@compat abstract type AbstractSimplex{S, T} <: StaticVector{S, T} end """ @@ -40,7 +40,7 @@ This is for a simpler implementation. It applies to infinite dimensions. The structure of this type is designed to allow embedding in higher-order spaces by parameterizing on `T`. """ -immutable Simplex{S, T} <: AbstractSimplex{T} +immutable Simplex{S, T} <: AbstractSimplex{S, T} data::NTuple{S, T} (::Type{Simplex{S, T}}){S, T}(x::NTuple{S, T}) = new{S, T}(x) (::Type{Simplex{S, T}}){S, T}(x::NTuple{S}) = new{S, T}(StaticArrays.convert_ntuple(T, x)) diff --git a/test/meshes.jl b/test/meshes.jl index 848d0e1..30f497d 100644 --- a/test/meshes.jl +++ b/test/meshes.jl @@ -25,8 +25,8 @@ using GeometryTypes: slice @test hasvertices(axis) @test hasfaces(axis) @test hasnormals(axis) - @test !( hascolors(axis) ) - end + @test !hascolors(axis) +end @testset "Show" begin baselen = 0.4f0 @@ -157,3 +157,21 @@ end end end + + +using GeometryTypes +attributes = Dict{Symbol, Any}() +attributes[:faces] = GLTriangle[(1,2,3), (3, 2, 1)] +attributes[:vertices] = rand(Point3f0, 3) +attributes[:normals] = rand(Normal{3, Float32}, 3) +@which HomogenousMesh(attributes) +# M = HomogenousMesh +# attribs = attributes +# newfields = map(fieldnames(HomogenousMesh)) do field +# target_type = fieldtype(M, field) +# default = fieldtype(HomogenousMesh, field) <: Vector ? Void[] : nothing +# get(attribs, field, default) +# end + +x = GeometryTypes.homogenousmesh(attributes) +GLNormalMesh(x) From 67f8535b258d0fedad094e92527fc9e22153f74b Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 25 Apr 2017 12:23:46 +0200 Subject: [PATCH 17/18] don't rely on Iterators anymore, since it doesn't work with precompilation --- REQUIRE | 1 - src/GeometryTypes.jl | 1 - src/lines.jl | 75 ++++++++++++++++++++++++++++++++++++++++++-- src/polygons.jl | 6 ++-- 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/REQUIRE b/REQUIRE index 13fb67c..f2b98da 100644 --- a/REQUIRE +++ b/REQUIRE @@ -2,5 +2,4 @@ julia 0.6- StaticArrays ColorTypes Compat 0.18 -Iterators FixedPointNumbers diff --git a/src/GeometryTypes.jl b/src/GeometryTypes.jl index 8e98ad6..4f71eef 100644 --- a/src/GeometryTypes.jl +++ b/src/GeometryTypes.jl @@ -5,7 +5,6 @@ using StaticArrays using StaticArrays.FixedSizeArrays using ColorTypes -import Iterators import FixedPointNumbers # U8 diff --git a/src/lines.jl b/src/lines.jl index a9496c7..556f405 100644 --- a/src/lines.jl +++ b/src/lines.jl @@ -56,15 +56,84 @@ function simple_concat{P}(vec, range, endpoint::P) result end + +# Taken from Iterators.jl, since it's not possible to use Iterators.jl on 0.6 with precompilation + +immutable Partition{I, N} + xs::I + step::Int +end +iteratorsize{T<:Partition}(::Type{T}) = SizeUnknown() + +Base.eltype{I, N}(::Type{Partition{I, N}}) = NTuple{N, eltype(I)} +function partition{I}(xs::I, n::Int) + Partition{I, n}(xs, n) +end + +function partition{I}(xs::I, n::Int, step::Int) + if step < 1 + throw(ArgumentError("Partition step must be at least 1.")) + end + + Partition{I, n}(xs, step) +end + +function Base.start{I, N}(it::Partition{I, N}) + p = Vector{eltype(I)}(N) + s = start(it.xs) + for i in 1:(N - 1) + if done(it.xs, s) + break + end + (p[i], s) = next(it.xs, s) + end + (s, p) +end + +function Base.next{I, N}(it::Partition{I, N}, state) + (s, p0) = state + (x, s) = next(it.xs, s) + ans = p0; ans[end] = x + + p = similar(p0) + overlap = max(0, N - it.step) + for i in 1:overlap + p[i] = ans[it.step + i] + end + + # when step > n, skip over some elements + for i in 1:max(0, it.step - N) + if done(it.xs, s) + break + end + (x, s) = next(it.xs, s) + end + + for i in (overlap + 1):(N - 1) + if done(it.xs, s) + break + end + + (x, s) = next(it.xs, s) + p[i] = x + end + + (tuple(ans...), (s, p)) +end + +Base.done(it::Partition, state) = done(it.xs, state[1]) + + + """ Finds all self intersections of polygon `points` """ function self_intersections{N,T}(points::Vector{Point{N,T}}) sections = Point{N,T}[] intersections = Int[] - wraparound = i->mod1(i, length(points)-1) - for (i, (a,b)) in enumerate(Iterators.partition(points, 2, 1)) - for (j, (a2, b2)) in enumerate(Iterators.partition(points, 2, 1)) + wraparound = i-> mod1(i, length(points) - 1) + for (i, (a,b)) in enumerate(partition(points, 2, 1)) + for (j, (a2, b2)) in enumerate(partition(points, 2, 1)) is1, is2 = wraparound(i+1), wraparound(i-1) if i!=j && is1!=j && is2!=j && !(i in intersections) && !(j in intersections) intersected, p = GeometryTypes.intersects(LineSegment(a,b), LineSegment(a2, b2)) diff --git a/src/polygons.jl b/src/polygons.jl index 8b32a29..2dfd767 100644 --- a/src/polygons.jl +++ b/src/polygons.jl @@ -52,7 +52,7 @@ function snip{N, T}( return false end - for p=1:n + for p = 1:n ((p == u) || (p == v) || (p == w)) && continue; P = contour[V[p]] if InsideTriangle(A, B, C, P) @@ -94,8 +94,8 @@ function polygon2faces{P<:Point}( #= remove nv-2 Vertices, creating 1 triangle every time =# count = 2*nv #= error detection =# - v=nv - while nv>2 + v = nv + while nv > 2 #= if we loop, it is probably a non-simple polygon =# if 0 >= count return result From 00dae03a8533bcc9610a0e9d8edeabb7d2ba8853 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 25 Apr 2017 12:24:06 +0200 Subject: [PATCH 18/18] workaround https://github.com/JuliaLang/julia/issues/21545 --- src/typeutils.jl | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/typeutils.jl b/src/typeutils.jl index f94193b..95c47c7 100644 --- a/src/typeutils.jl +++ b/src/typeutils.jl @@ -1,10 +1,11 @@ using Compat.TypeUtils -eltype_or(::Type{<: AbstractGeometry{N, T} where N}, or) where T = T -eltype_or(::Type{<: AbstractGeometry{N, T} where N where T}, or) = or +eltype_or(::Type{G}, or) where G <: (AbstractGeometry{N, T} where N) where T = T +eltype_or(::Type{G}, or) where G <: (AbstractGeometry{N, T} where {N, T}) = or + +ndims_or(::Type{G}, or) where G <: (AbstractGeometry{N, T} where T) where N = N +ndims_or(::Type{G}, or) where G <: (AbstractGeometry{N, T} where {N, T}) = or -ndims_or(::Type{<: AbstractGeometry{N, T} where T}, or) where N = N -ndims_or(::Type{<: AbstractGeometry{N, T} where N where T}, or) = or Base.eltype(T::Type{<:AbstractGeometry}) = eltype_or(T, Any)