-
Notifications
You must be signed in to change notification settings - Fork 54
Expand file tree
/
Copy pathConstructiveSolidGeometry.jl
More file actions
135 lines (106 loc) · 5.88 KB
/
ConstructiveSolidGeometry.jl
File metadata and controls
135 lines (106 loc) · 5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# """
# # module ConstructiveSolidGeometry
# """
module ConstructiveSolidGeometry
# Base Packages
using LinearAlgebra
# # Other Packages
using IntervalSets
using JSON
using Parameters
using PolygonOps
using Polynomials
using RecipesBase
using Rotations
using StaticArrays
using Statistics
using Unitful
using YAML
using OrderedCollections: OrderedDict
import InverseFunctions
using InverseFunctions: inverse
import Base: in, *, +, -, &, size, zero
abstract type AbstractCoordinateSystem end
abstract type Cartesian <: AbstractCoordinateSystem end
abstract type Cylindrical <: AbstractCoordinateSystem end
const CoordinateSystemType = Union{Type{Cartesian}, Type{Cylindrical}}
import Base: print, show
print(io::IO, ::Type{Cartesian}) = print(io, "Cartesian")
print(io::IO, ::Type{Cylindrical}) = print(io, "Cylindrical")
show(io::IO, CS::CoordinateSystemType) = print(io, CS)
show(io::IO,::MIME"text/plain", CS::CoordinateSystemType) = show(io, CS)
# Tuples with ticks to sample with differently spaced ticks
const CartesianTicksTuple{T} = NamedTuple{(:x,:y,:z), NTuple{3,Vector{T}}}
const CylindricalTicksTuple{T} = NamedTuple{(:r,:φ,:z), NTuple{3,Vector{T}}}
abstract type AbstractGeometry{T <: AbstractFloat} end
abstract type AbstractPrimitive{T} <: AbstractGeometry{T} end
abstract type ClosedPrimitive end
abstract type OpenPrimitive end
abstract type AbstractVolumePrimitive{T, CO <: Union{ClosedPrimitive, OpenPrimitive}} <: AbstractPrimitive{T} end
abstract type AbstractSurfacePrimitive{T} <: AbstractPrimitive{T} end
abstract type AbstractLinePrimitive{T} <: AbstractPrimitive{T} end
abstract type AbstractConstructiveGeometry{T} <: AbstractGeometry{T} end
include("Units.jl")
include("PointsAndVectors/PointsAndVectors.jl")
affine_frame(p::AbstractPrimitive) = LocalAffineFrame(origin(p), rotation(p))
frame_transformation(a::AbstractAffineFrame, b::AbstractPrimitive) = frame_transformation(a, affine_frame(b))
frame_transformation(a::AbstractPrimitive, b::AbstractAffineFrame) = frame_transformation(affine_frame(a), b)
frame_transformation(a::AbstractPrimitive, b::AbstractPrimitive) = frame_transformation(affine_frame(a), affine_frame(b))
_csg_convert_args(::Type{T}, r::Real) where T = convert(T, r)
_csg_convert_args(::Type{T}, r::Tuple) where T = broadcast(x -> _csg_convert_args(T, x), r)
_csg_convert_args(::Type{T}, r::Nothing) where T = nothing
_csg_get_promoted_eltype(::Type{T}) where {T <: AbstractArray} = eltype(T)
_csg_get_promoted_eltype(::Type{T}) where {T <: Real} = T
_csg_get_promoted_eltype(::Type{Nothing}) = Int
_csg_get_promoted_eltype(::Type{CartesianPoint{T}}) where {T<:Real} = T
_csg_get_promoted_eltype(::Type{Tuple{T}}) where {T<:Real} = T
_csg_get_promoted_eltype(::Type{Tuple{T1,T2}}) where {T1<:Real, T2<:Real} = promote_type(T1, T2)
_csg_get_promoted_eltype(::Type{Tuple{T1,T2}}) where {T1<:Union{Real, Tuple}, T2<:Union{Real, Tuple}} = promote_type(_csg_get_promoted_eltype(T1), _csg_get_promoted_eltype(T2))
_csg_get_promoted_eltype(::Type{Tuple{Nothing,T2}}) where {T2<:Union{Real, Tuple}} = _csg_get_promoted_eltype(T2)
_csg_get_promoted_eltype(::Type{Tuple{T1,Nothing}}) where {T1<:Union{Real, Tuple}} = _csg_get_promoted_eltype(T1)
_handle_phi(φ, rotation) = (φ, rotation)
_handle_phi(φ::Tuple, rotation) = (abs(φ[2]-φ[1]), rotation*RotZ(φ[1]))
rotation(p::AbstractPrimitive) = p.rotation
origin(p::AbstractPrimitive) = p.origin
# ToDo: Completely replace by frame_transformation and remove:
_transform_into_global_coordinate_system(pt::CartesianPoint, p::AbstractPrimitive) = frame_transformation(p, global_frame, pt)
_transform_into_global_coordinate_system(v::CartesianVector, p::AbstractPrimitive) = frame_transformation(p, global_frame, v)
_transform_into_global_coordinate_system(pts::AbstractVector{<:CartesianPoint}, p::AbstractPrimitive) =
frame_transformation(p, global_frame, pts)
_transform_into_object_coordinate_system(pt::CartesianPoint, p::AbstractPrimitive) = frame_transformation(global_frame, p, pt)
_transform_into_object_coordinate_system(v::CartesianVector, p::AbstractPrimitive) = frame_transformation(global_frame, p, v)
in(pt::CartesianPoint{T}, p::AbstractPrimitive{T}, csgtol::T = csg_default_tol(T)) where {T} =
_in(_transform_into_object_coordinate_system(pt, p), p; csgtol = csgtol)
in(pt::CylindricalPoint{T}, p::AbstractPrimitive{T}, csgtol::T = csg_default_tol(T)) where {T} =
in(CartesianPoint(pt), p, csgtol)
"""
extreme_points(es::AbstractPrimitive{T}) where {T}
Generic fallback of `extreme_points` for any primitive.
Returns 6 `CartesianPoint`s in both directions of each cartesian axes (x, y and z)
around the origin of the primitive with distance determined by `extremum(es)`,
which returns the maximum distance of an primitive to its origin.
## Arguments
* `es::AbstractPrimitive{T}`: Any primitive, e.g. a `Box`.
"""
function extreme_points(es::AbstractPrimitive{T}) where {T}
o = origin(es)
r = extremum(es)
vX = r * CartesianVector{T}(one(T), zero(T), zero(T))
vY = r * CartesianVector{T}(zero(T), one(T), zero(T))
vZ = r * CartesianVector{T}(zero(T), zero(T), one(T))
SVector{6,CartesianPoint{T}}(
o - vX, o + vX, o - vY, o + vY, o - vZ, o + vZ,
)
end
get_scale(es::AbstractPrimitive) = extremum(es)
include("Transformations.jl")
include("GeometryRounding.jl")
include("VolumePrimitives/VolumePrimitives.jl")
include("LinePrimitives/LinePrimitives.jl")
include("SurfacePrimitives/SurfacePrimitives.jl")
include("Intervals.jl")
include("CSG.jl")
include("IO.jl")
# Plotting
include("plotting/plotting.jl")
end