Skip to content

Commit

Permalink
first implementation for FreeForm optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
cserteGT3 committed Jul 4, 2023
1 parent ddafc74 commit 169d33b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 18 deletions.
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Meshes = "eacbb407-ea5a-433e-ab97-5258b1ca43fa"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

Expand Down
4 changes: 4 additions & 0 deletions src/BlankLocalizationCore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module BlankLocalizationCore
using JuMP
using DataFrames: DataFrame, names, nrow
using PrettyTables: pretty_table, ft_nonothing, tf_html_minimalist
using Meshes: SimpleMesh, vertices, boundingbox
using Logging: @warn
using LinearAlgebra: norm
using Printf: @sprintf
Expand Down Expand Up @@ -33,6 +34,9 @@ export allowancetable,
"""Union type for `Float64` and `Nothing`."""
const FON = Union{Nothing,Float64}

"""A 3 long vector of `nothing`s."""
const NOTHING3 = [nothing, nothing, nothing]

"""Create a homogeneous vector by appending 1 to the end of a vector."""
HV(v) = vcat(v, 1)

Expand Down
42 changes: 34 additions & 8 deletions src/geometries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,29 @@ struct IsFreeForm <: GeometryStyle end
#GeometryStyle(::Type) = IsPrimitive()

# Functions to be implemented to comply with the interface:
# radius(HoleGeometry) - return the radius of a hole feature
# primitive features have feature points
featurepoint(x::T) where {T} = featurepoint(GeometryStyle(T), x)
featurepoint(::IsPrimitive, x) = x.p
function featurepoint(::IsFreeForm, x)
error("Function `featurepoint` is not defined for `IsFreeForm`` features")
end

# Functions to be implemented to comply with the interface:
# free form geometries have surfacepoints
# return all points of a free form surface
surfacepoints(x::T) where {T} = surfacepoints(GeometryStyle(T), x)
#surfacepoints(::IsFreeForm, x) = x.p
function surfacepoints(::IsPrimitive, x)
error("Function `surfacepoints` is not defined for `IsFreeForm`` features")
end

# free form geometries have surfacepoints
# return only those points, that may define active constraints
filteredsurfacepoints(x::T) where {T} = filteredsurfacepoints(GeometryStyle(T), x)
function filteredsurfacepoints(::IsPrimitive, x)
error("Function `surfacepoints` is not defined for `IsPrimitive`` features")
end

# radius is only defined for hole like features that are IsPrimitive
featureradius(x::T) where {T<:AbstractHoleGeometry} = featureradius(GeometryStyle(T), x)
featureradius(::IsPrimitive, x) = x.r
Expand Down Expand Up @@ -73,19 +88,28 @@ A simple mesh hole geometry, that contains the mesh of the hole's surface and th
hull of the points (see our paper for details).
"""
struct MeshHole <: AbstractHoleGeometry
mesh
chull
surface::SimpleMesh
convexhull::Vector{Vector{Float64}}
end

GeometryStyle(::Type{MeshHole}) = IsFreeForm()

function filteredsurfacepoints(::IsFreeForm, x::MeshHole)
return x.convexhull
end

"""
MeshPlane <: AbstractPlaneGeometry
A simple mesh plane geometry, that contains the mesh of a planar face.
"""
struct MeshPlane <: AbstractPlaneGeometry
mesh
surface::SimpleMesh
end

function filteredsurfacepoints(::IsFreeForm, x::MeshPlane)
bbox = boundingbox(x.surface)
return [bbox.min.coords, bbox.max.coords]
end

GeometryStyle(::Type{MeshPlane}) = IsFreeForm()
Expand Down Expand Up @@ -141,15 +165,15 @@ struct HoleLocalizationFeature{R<:AbstractHoleGeometry,M<:AbstractHoleGeometry}
machined::M
end

GeometryStyle(::Type{HoleLocalizationFeature{R,M}}) where {R,M} = GeometryStyle(R)
#GeometryStyle(::Type{HoleLocalizationFeature{R,M}}) where {R,M} = GeometryStyle(R)

struct PlaneLocalizationFeature{R<:AbstractPlaneGeometry,M<:AbstractPlaneGeometry} <: LocalizationFeature{R,M}
descriptor::FeatureDescriptor
rough::R
machined::M
end

GeometryStyle(::Type{PlaneLocalizationFeature{R,M}}) where {R,M} = GeometryStyle(R)
#GeometryStyle(::Type{PlaneLocalizationFeature{R,M}}) where {R,M} = GeometryStyle(R)

getfeaturename(f::LocalizationFeature) = getfeaturename(f.descriptor)
getpartzero(f::LocalizationFeature) = getpartzero(f.descriptor)
Expand All @@ -162,6 +186,8 @@ getmachinedfeaturepoint(f::LocalizationFeature) = featurepoint(f.machined)
getmachinedradius(f::LocalizationFeature) = featureradius(f.machined)
getroughradius(f::LocalizationFeature) = featureradius(f.rough)

getroughfilteredpoints(f::LocalizationFeature) = filteredsurfacepoints(f.rough)

function getmachinedfeaturepointindatum(f::LocalizationFeature)
@assert hasmachined(f)
v = getmachinedfeaturepoint(f)
Expand Down Expand Up @@ -215,11 +241,11 @@ end
function problemtype(mop::MultiOperationProblem)
# problem type is depending on the rough geometries: IsPrimitive or IsFreeForm
# if there is at least one IsFreeForm rough geometry -> hybrid problem
holetypes = GeometryStyle.(typeof.(mop.holes))
holetypes = GeometryStyle.(typeof.(x.rough for x in mop.holes))
for ht in holetypes
ht === IsFreeForm() && return :HybridProblem
end
planetypes = GeometryStyle.(typeof.(mop.planes))
planetypes = GeometryStyle.(typeof.(x.rough for x in mop.planes))
for pt in planetypes
pt === IsFreeForm() && return :HybridProblem
end
Expand Down
57 changes: 49 additions & 8 deletions src/optimization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ function addhole2model!(model, hole::HoleLocalizationFeature{R,M}, ipzmatricedic
return addhole2model!(GeometryStyle(R), model, hole, ipzmatricedict)
end

function addhole2model!(::IsFreeForm, model, hole, ipzmatricedict)
error("Not yet implemented for FreeForm geometries")
end

function addhole2model!(::IsPrimitive, model, hole, ipzmatricedict)
# access registered variables
minAllowance = model[:minAllowance]
Expand All @@ -28,15 +24,36 @@ function addhole2model!(::IsPrimitive, model, hole, ipzmatricedict)
return model
end

function addhole2model!(::IsFreeForm, model, hole, ipzmatricedict)
# access registered variables
minAllowance = model[:minAllowance]

# filtered surface points of a free form surface
qs = getroughfilteredpoints(hole)
qiter = 1:length(qs)

# register distance variable:
dxy = @variable(model, [qiter], base_name = string("d_xy_", getfeaturename(hole)), lower_bound = 0.0)

pzn = getpartzeroname(hole)
v_machined = getmachinedfeaturepoint(hole)
r_machined = getmachinedradius(hole)
# equation (4)
for (i, q) in enumerate(qs)
d_f = @expression(model, HV(v_machined)-ipzmatricedict[pzn]*HV(q))
# equation (5)
@constraint(model, dxy[i]*dxy[i] >= d_f[1]*d_f[1] + d_f[2]*d_f[2])
# equation (6)
@constraint(model, dxy[i] - r_machined >= minAllowance)
end
return model
end

# dispatch on GeometryStyle trait
function addplane2model!(model, plane::PlaneLocalizationFeature{R,M}, ipzmatricedict) where {R,M}
return addplane2model!(GeometryStyle(R), model, plane, ipzmatricedict)
end

function addplane2model!(::IsFreeForm, model, plane, ipzmatricedict)
error("Not yet implemented for FreeForm geometries")
end

function addplane2model!(::IsPrimitive, model, plane, ipzmatricedict)
# access registered variables
minAllowance = model[:minAllowance]
Expand All @@ -55,6 +72,30 @@ function addplane2model!(::IsPrimitive, model, plane, ipzmatricedict)
return model
end

function addplane2model!(::IsFreeForm, model, plane, ipzmatricedict)
# access registered variables
minAllowance = model[:minAllowance]

# filtered surface points of a free form surface
qs = getroughfilteredpoints(plane)
qiter = 1:length(qs)

# register distance variable:
dz = @variable(model, [qiter], base_name = string("d_z_", getfeaturename(plane)))

pzn = getpartzeroname(plane)
v_machined = getmachinedfeaturepoint(plane)
# equation (4)
for (i, q) in enumerate(qs)
d_f = @expression(model, HV(v_machined)-ipzmatricedict[pzn]*HV(q))
# equation (5)
@constraint(model, dz[i] == d_f[3])
# equation (6)
@constraint(model, -1*dz[i] >= minAllowance)
end
return model
end

function addtolerances2model!(model, mop::MultiOperationProblem, pzmatricedict)
for (i, t) in enumerate(mop.tolerances)
# access registered variables
Expand Down
2 changes: 0 additions & 2 deletions src/resultevaluation.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const NOTHING3 = [nothing, nothing, nothing]

function allowancetable(mop::MultiOperationProblem)
df = DataFrame(name=String[], partzeroname=String[], machinedx=FON[], machinedy=FON[],
machinedz=FON[], roughx=FON[], roughy=FON[], roughz=FON[], machinedr=FON[],
Expand Down

0 comments on commit 169d33b

Please sign in to comment.