Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@ Any primitve or operation must implement two core operations; `FRep` and `HyperR

In the next line we actually perform the meshing operation. We call the meshtype with the implicit function we created, `f`, in the bounds generated by `HyperRectangle`, uniformly sample the space by `samples`, and actually generate the triangular meshing using `algorithm`. In this case, the defaults are `samples=(128,128,128)` and `algorithm=MarchingCubes()`.

In the loop `for i = 2:length(primitives) ... end` we handle additional primitives passed to our meshing function so you can create a single mesh output from several different objects. In order to maintain performance and resolution these are not `union`ed.
In the loop `for i = 2:length(primitives) ... end` we handle additional primitives passed to our meshing function so you can create a single mesh output from several different objects. In order to maintain performance and resolution these are not `union`ed. This means if primitives are passed as seperate arguments ther will each get their own triangles.
105 changes: 93 additions & 12 deletions examples/fea.jl
Original file line number Diff line number Diff line change
@@ -1,20 +1,101 @@
using Descartes
using DistMesh
using GeometryTypes
using StaticArrays
using Makie
#using Colors

Cylinder=Descartes.Cylinder
translate=Descartes.translate
rotate=Descartes.rotate

# params
beam_size = [50,10,10]
hole_ct = 5
hole_d = 3
function beam(beam_size = [50,10,10],
hole_ct = 5,
hole_d = 3)

# computations
hole_interval = beam_size[1]/(hole_ct + 1)

c = Cuboid(beam_size)

for i = 1:hole_ct
h = translate([hole_interval*i, -1, beam_size[3]/2])*
rotate(-pi/2, [1,0,0])*
rotate(-pi/6, [0,1,0])* # adversarial case
Cylinder(hole_d/2, beam_size[2]+2, center=false)
c = diff(c, h)
end
c
end

function deadmau5()
diff(union(Descartes.Sphere(5),
translate([4,2,0])Descartes.Sphere(4),
translate([-4,2,0])Descartes.Sphere(4)),
translate([5,2,3])Descartes.Sphere(3),
translate([-5,2,3])Descartes.Sphere(3))
end

b = beam([10,10,10],1, 3)
#b = Descartes.Sphere(5)
f(x) = FRep(b, x)
m = GLNormalMesh(b)
scene = mesh(m, color=:blue)
display(scene)
sleep(5)
h = HyperRectangle(b)
@show f(SVector(1,1,1))
@time p, t, statsdata = distmesh(f, HUniform(), 0.9, DistMeshSetup(distribution=:packed,sort_interval=20,deltat=0.05,nonlinear=true,sort=true), origin=h.origin, widths=h.widths, stats=true)
@show length(p), length(t)
VertType = eltype(p)
pair = Tuple{Int32,Int32}[] # edge indices (Int32 since we use Tetgen)

# computations
hole_interval = beam_size[1]/(hole_ct + 1)
pair=resize!(pair, length(t)*6)
ls = Pair{VertType,VertType}[]

c = Cuboid(beam_size)
for i in eachindex(t)
for ep in 1:6
p1 = t[i][DistMesh.tetpairs[ep][1]]
p2 = t[i][DistMesh.tetpairs[ep][2]]
if p1 > p2
pair[(i-1)*6+ep] = (p2,p1)
else
pair[(i-1)*6+ep] = (p1,p2)
end
end
end

sort!(pair)
unique!(pair)

for i = 1:hole_ct
h = translate([hole_interval*i, -1, beam_size[3]/2])*
rotate(-pi/2, [1,0,0])*
Cylinder(hole_d/2, beam_size[2]+2, center=false)
global c = diff(c, h)
# makie vis

resize!(ls, length(pair))
for i = 1:length(pair)
ls[i] = p[pair[i][1]] => p[pair[i][2]]
end
scene = Makie.linesegments(ls)
display(scene)

qualities = DistMesh.triangle_qualities(p,t)

statsdata
using Plots

qual_hist = Plots.histogram(qualities, title = "Quality", legend=false)
avg_plt = Plots.plot(statsdata.average_qual, title = "Average Quality", legend=false, ylabel="Quality")
vline!(statsdata.retriangulations, line=(0.2, :dot, [:red]))
med_plt = Plots.plot(statsdata.median_qual, title = "Median Quality", legend=false, ylabel="Quality")
vline!(statsdata.retriangulations, line=(0.2, :dot, [:red]))
maxdp_plt = Plots.plot(statsdata.maxdp, title = "Max Displacement", legend=false, ylabel="Edge Displacement")
vline!(statsdata.retriangulations, line=(0.2, :dot, [:red]))
maxmove_plt = Plots.plot(statsdata.maxmove, title = "Max Move", legend=false, ylabel="Point Displacement")
vline!(statsdata.retriangulations, line=(0.2, :dot, [:red]))
plt = Plots.plot(avg_plt, med_plt,maxdp_plt,maxmove_plt,layout=(2,2), xlabel="Iteration", )
savefig(plt, "result_stat.svg")
savefig(qual_hist, "result_qual.svg")



save("fea.ply",HomogenousMesh(c))
#save("fea.ply",HomogenousMesh(c))
4 changes: 4 additions & 0 deletions src/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ end
#

# Union
@nospecialize

function CSGUnion(l::AbstractPrimitive{N1,T1}, r::AbstractPrimitive{N2,T2}) where {N1, N2, T1, T2}
N1 == N2 || error("cannot create CSG between objects in R$N1 and R$N2")
return CSGUnion{N1,T1, typeof(l), typeof(r)}(l,r)
Expand Down Expand Up @@ -132,3 +134,5 @@ end
function LinearExtrude(p::AbstractPrimitive{2,T}, d) where {T}
LinearExtrude{3, T, typeof(p)}(p, convert(T, d), SMatrix{4,4}(1.0*I), SMatrix{4,4}(1.0*I))
end

@specialize
23 changes: 17 additions & 6 deletions src/frep.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# http://en.wikipedia.org/wiki/Function_representation

function fmax(x::T1,y::T2) where {T1, T2}
if x > zero(T1) && y > zero(T2)
return sqrt(x^2+y^2)
end
return max(x,y)
end

fmax(x,y,z) = fmax(fmax(x,y),z)
fmax(a,b,c,d) = fmax(fmax(a,b),fmax(c,d))
fmax(a,b,c,d,e,f) = fmax(fmax(a,b,c,d),fmax(e,f))

function _radius(a,b,r)
if abs(a-b) >= r
return min(a,b)
Expand All @@ -21,7 +32,7 @@ function FRep(p::Cylinder, v)
x = v[1]*it[1,1]+v[2]*it[1,2]+v[3]*it[1,3]+it[1,4]
y = v[1]*it[2,1]+v[2]*it[2,2]+v[3]*it[2,3]+it[2,4]
z = v[1]*it[3,1]+v[2]*it[3,2]+v[3]*it[3,3]+it[3,4]
max(-z+p.bottom, z-p.height-p.bottom, sqrt(x*x + y*y) - p.radius)
fmax(-z+p.bottom, z-p.height-p.bottom, sqrt(x*x + y*y) - p.radius)
end

function FRep(p::Circle, v)
Expand All @@ -39,7 +50,7 @@ function FRep(p::Cuboid, v)
z = v[1]*it[3,1]+v[2]*it[3,2]+v[3]*it[3,3]+it[3,4]
dx, dy, dz = p.dimensions
lbx, lby,lbz = p.lowercorner
max(-x+lbx, x-dx-lbx,
fmax(-x+lbx, x-dx-lbx,
-y+lby, y-dy-lby,
-z+lbz, z-dz-lbz)
end
Expand All @@ -50,7 +61,7 @@ function FRep(p::Square, v)
y = v[1]*it[2,1]+v[2]*it[2,2]+it[2,3]
dx, dy = p.dimensions
lbx, lby = p.lowercorner
max(-x+lbx, x-dx-lbx,
fmax(-x+lbx, x-dx-lbx,
-y+lby, y-dy-lby)
end

Expand All @@ -59,11 +70,11 @@ function FRep(u::CSGUnion, v)
end

function FRep(u::CSGDiff, v)
max(FRep(u.left, v), -FRep(u.right, v))
fmax(FRep(u.left, v), -FRep(u.right, v))
end

function FRep(u::CSGIntersect, v)
max(FRep(u.left, v), FRep(u.right, v))
fmax(FRep(u.left, v), FRep(u.right, v))
end

function FRep(s::Shell, v)
Expand Down Expand Up @@ -107,5 +118,5 @@ function FRep(p::LinearExtrude, v)
y = v[1]*it[2,1]+v[2]*it[2,2]+v[3]*it[2,3]+it[2,4]
z = v[1]*it[3,1]+v[2]*it[3,2]+v[3]*it[3,3]+it[3,4]
r = FRep(p.primitive, v)
max(max(-z,z-p.distance), r)
fmax(fmax(-z,z-p.distance), r)
end