@@ -322,21 +322,26 @@ function parse_geometry(e::Ellipsoid{T,<:Any, TR, Nothing, Nothing}, x_solids::X
322
322
nothing
323
323
end
324
324
325
- # @inline parse_θ(::Type{T}, θ::Nothing) where {T} = (T(0), T(360), "deg")
326
- # @inline parse_θ(::Type{T}, θ::Tuple{T, T}) where {T} = throw(AssertionError("Torus: θ values are currently not supported"))
327
- function parse_geometry (e:: Torus , x_solids:: XMLElement , x_define:: XMLElement , id:: Integer , pf:: AbstractString , v:: Bool ):: Nothing
328
- if has_volume (e, v)
325
+ function parse_geometry (e:: Torus{T,<:Any,<:Any,Nothing,Nothing} , x_solids:: XMLElement , x_define:: XMLElement , id:: Integer , pf:: AbstractString , v:: Bool ):: Nothing where {T}
326
+
327
+ # if e.r_torus == 0, the torus is basically a sphere => convert it to a sphere
328
+ if iszero (e. r_torus)
329
+ parse_geometry (
330
+ if isa (e. r_tube, Tuple)
331
+ CSGDifference (
332
+ Ellipsoid {T} (r = e. r_tube[2 ], origin = e. origin, rotation = e. rotation),
333
+ Ellipsoid {T} (r = e. r_tube[1 ], origin = e. origin, rotation = e. rotation)
334
+ )
335
+ else
336
+ Ellipsoid {T} (r = e. r_tube, origin = e. origin, rotation = e. rotation)
337
+ end ,
338
+ x_solids, x_define, id, pf, v
339
+ )
340
+
341
+ elseif has_volume (e, v)
329
342
y = new_child (x_solids, " torus" )
330
- # phi, aunit = parse_φ(T, e.φ)
331
- # theta1, theta2, aunit = parse_θ(T, e.θ)
332
343
333
- rmin, rmax = if isa (e. r_tube, Tuple)
334
- e. r_tube[1 ], e. r_tube[2 ]
335
- else
336
- 0 , e. r_tube
337
- end
338
-
339
- # rmin = 0
344
+ rmin, rmax = isa (e. r_tube, Tuple) ? e. r_tube : (0 , e. r_tube)
340
345
341
346
set_attributes (y, OrderedDict (
342
347
" name" => pf * string (id),
@@ -348,7 +353,48 @@ function parse_geometry(e::Torus, x_solids::XMLElement, x_define::XMLElement, id
348
353
" lunit" => SolidStateDetectors. internal_length_unit,
349
354
" aunit" => " deg"
350
355
))
351
-
356
+ end
357
+ end
358
+
359
+ function _rectangle_point (x:: T ):: Tuple{T,T} where {T <: Real }
360
+ return (
361
+ clamp (tand (abs (mod (x- 90 ,360 )- 180 )- 90 ),- 1 ,1 ),
362
+ clamp (tand (abs (mod ( x,360 )- 180 )- 90 ),- 1 ,1 )
363
+ )
364
+ end
365
+
366
+ function parse_geometry (e:: Torus{T,<:Any,<:Any,Nothing,Tuple{T,T}} , x_solids:: XMLElement , x_define:: XMLElement , id:: Integer , pf:: AbstractString , v:: Bool ):: Nothing where {T}
367
+ if has_volume (e, v)
368
+
369
+ theta1:: T , theta2:: T = rad2deg .(e. θ)
370
+ rmax = isa (e. r_tube, Tuple) ? e. r_tube[2 ] : e. r_tube
371
+
372
+ parse_geometry (
373
+ CSGIntersection (
374
+ # create full-θ Torus
375
+ Torus (r_torus = e. r_torus, r_tube = e. r_tube, φ = e. φ, θ = nothing , origin = e. origin, rotation = e. rotation),
376
+
377
+ # create Polycone to intersect with
378
+ begin
379
+ points = Tuple{T,T}[(zero (T), zero (T))]
380
+ push! (points, _rectangle_point (theta2))
381
+ tmp:: T = theta2 - mod (theta2 - 45 , 90 )
382
+ while theta1 < tmp && tmp > 0
383
+ push! (points, _rectangle_point (tmp))
384
+ tmp -= 90
385
+ end
386
+ push! (points, _rectangle_point (theta1))
387
+ push! (points, (zero (T), zero (T)))
388
+ Polycone (
389
+ r = getindex .(points,1 ) .* rmax .+ e. r_torus,
390
+ z = getindex .(points,2 ) .* rmax,
391
+ origin = e. origin,
392
+ rotation = e. rotation
393
+ )
394
+ end
395
+ ),
396
+ x_solids, x_define, id, pf, v
397
+ )
352
398
end
353
399
end
354
400
0 commit comments