Module Dometyl.Connect

type t = {
  1. scad : OSCADml.Scad.d3;
  2. outline : OCADml.Path3.t;
  3. inline : OCADml.Path3.t;
}

Shape(s) connecting walls together, and the points along the outside and inside of the foot.

val translate : OCADml.V3.t -> t -> t
val xtrans : float -> t -> t
val ytrans : float -> t -> t
val ztrans : float -> t -> t
val rotate : ?about:OCADml.V3.t -> OCADml.V3.t -> t -> t
val xrot : ?about:OCADml.V3.t -> float -> t -> t
val yrot : ?about:OCADml.V3.t -> float -> t -> t
val zrot : ?about:OCADml.V3.t -> float -> t -> t
val axis_rotate : ?about:OCADml.V3.t -> OCADml.V3.t -> float -> t -> t
val quaternion : ?about:OCADml.V3.t -> OCADml.Quaternion.t -> t -> t
val scale : OCADml.V3.t -> t -> t
val xscale : float -> t -> t
val yscale : float -> t -> t
val zscale : float -> t -> t
val mirror : OCADml.V3.t -> t -> t
val affine : OCADml.Affine3.t -> t -> t
type config
val empty : t

An empty connection (shapeless with empty paths)

val clockwise_union : t list -> t

clockwise_union ts

Create a union of ts. They should be provided in clockwise order, such that the outline and inline of the resulting t are continous and in the clockwise direction.

val outline_2d : t -> OCADml.Path2.t

outline_2d t

Retrieve the outline points of t and project them to 2d vectors.

val inline_2d : t -> OCADml.Path2.t

inline_2d t

Retrieve the inline points of t and project them to 2d vectors.

val full_join : ?slices:int -> ?max_angle:float -> ?gap_fill:bool -> unit -> config

full_join ?slices ?max_angle ?gap_fill ()

Configure a full joining (sealed top to bottom) of neighbouring walls.

  • slices sets the number of intervening profiles over which the face of the starting wall morphs into the destination wall (default = 12)
  • if the angle between the heading of the start and destination walls is greater than max_angle (default = 1.4), pre-rotated faces will be projected out from each wall before the rest of the join is completed
  • if gap_fill is true (as is default), some effort will be made to close up any triangular gap there might be between the columns and the generated wall join
val spline : ?height:float -> ?d:float -> ?size:float -> ?fn:int -> ?min_step_dist:float -> ?fillet_d:[ `Abs of float | `Rel of float ] -> ?fillet_h:[ `Abs of float | `Rel of float ] -> ?corner:OCADml.Path3.Round.corner -> ?corner_fn:int -> ?max_edge_res:float -> ?end_shrink:float -> ?tight_threshold:float -> ?tight_d:float -> unit -> config

spline ()

Configure a base connection standing height tall between neighbouring walls that runs along a generated bezier spline path of fn points. The second and penultimate control points of which are offset d outward along the heading vectors of the input walls.

  • size corresponds to ~size parameter of Bezier3.of_path, setting the loosness of the bezier spline
  • min_step_dist constrains how close the profiles/slices of the sweep can be (discarded if they are not at least this distance off of the plane formed by the last). This is done to prevent (some of the possible) illegal self-intersecting meshes.
  • fillet_d and fillet_h describe a z-axis fillet, shrinking by the given height (absolute, or relative to height) over the specified distance (absolute, or relative to the length of the spline)
  • corner and corner_fn describe the roundover to apply to the top corners of the sweep profile
  • max_edge_res constrains the maximum resolution (defined as distance between points along the outline) of the sweep profile. Too high resolution can lead to "bunching" up of points during the sweep, especially with filleting that can introduce self-intersections into the mesh
  • end_shrink is a factor to scale down the first/final profiles of the sweep to help prevent poking through the walls (default = 0.025)
  • tight_threshold and tight_d set an angle vs distance ratio (sharp angle between proximal walls) at which d is replaced by a (lower) value more likely to generate an unbroken mesh. Basically, too high of a d step outward from the walls at the beginning of the spline can lead to sweeps which can't help but overlap themselves
val manual : ?west:(int -> config) -> ?north:(int -> config) -> ?south:(int -> config) -> ?east:(int -> config) -> ?east_link:config -> ?thumb_east:(int -> config) -> ?thumb_south:(int -> config) -> ?thumb_west:(int -> config) -> ?thumb_north:(int -> config) -> ?west_link:config -> Walls.t -> t

manual walls

Generate a complete perimeter t using lookups from wall index to config for each of the sides, and the "links" between the body and the thumb cluster.

val skeleton : ?height:float -> ?index_height:float -> ?thumb_height:float -> ?spline_d:float -> ?spline_size:float -> ?fn:int -> ?min_step_dist:float -> ?fillet_d:[ `Abs of float | `Rel of float ] -> ?fillet_h:[ `Abs of float | `Rel of float ] -> ?corner:OCADml.Path3.Round.corner -> ?corner_fn:int -> ?max_edge_res:float -> ?end_shrink:float -> ?tight_threshold:float -> ?tight_spline_d:float -> ?join_slices:int -> ?max_join_angle:float -> ?gap_fill:bool -> ?east_link:config -> ?west_link:config -> ?north_joins:(int -> bool) -> ?south_joins:(int -> bool) -> ?close_thumb:bool -> Walls.t -> t

skeleton walls

Generate a complete perimeter t for a skeletal case with (reasonable?) defaults. See full_join and spline for configuration parameters relevant to the particular connection styles included.

  • north_joins, south_joins, and close_thumb can be used to indicate that full wall joins should be generated at particular connections around the case, rather than the spline connectors that just run along the ground
val closed : ?height:float -> ?spline_d:float -> ?spline_size:float -> ?fn:int -> ?min_step_dist:float -> ?fillet_d:[ `Abs of float | `Rel of float ] -> ?fillet_h:[ `Abs of float | `Rel of float ] -> ?corner:OCADml.Path3.Round.corner -> ?corner_fn:int -> ?max_edge_res:float -> ?end_shrink:float -> ?tight_threshold:float -> ?tight_spline_d:float -> ?join_slices:int -> ?max_join_angle:float -> ?gap_fill:bool -> ?west_link:config -> ?east_link:config -> Walls.t -> t

closed walls

Generate a complete perimeter t for a (mostly) closed case with (reasonable?) defaults. See full_join and spline for configuration parameters relevant to the particular connection styles included.

This helper assumes that there are more walls in place than there would be for a skeletal case, as full_join is at its most appropriate when the walls being joined are direct neighbours (especially around corners).

Connections between the main body and the thumb cluster are not closed, as doing so would require more sealing logic prone to breaking, which goes against dometyls philosophy of allowing easy repositioning/re-orienting of the thumb cluster to suit the users hand. To adjust them, provide configurations with west_link and east_link.

val to_scad : t -> OSCADml.Scad.d3