Class Definition: geom.Region

drafting: geom.Region

A closed area of a plane, an outline with holes in it.

A geom.Region is what a solid is made from: solid.extrude, solid.revolve, solid.sweep, solid.loft and solid.helix each take one. It is the area inside one closed loop, the outline, less the areas inside any number of others, the holes. Each loop is a closed geom.Path of straight segments, arcs and splines, so a hole may have any shape: a circle, a slot, a square or a smooth closed geom.Spline. A hole goes right through whatever is made from the region; a recess of limited depth is a pocket, worked on the solid.

A region is always valid: every outline closed, none crossing or touching itself, every hole in the plane of the outline and strictly inside it, and no two holes overlapping or touching. An island inside a hole is not a region; union a second solid made from it. Open CASCADE checks the loops on their exact curves, at its own tolerance of 1e-7 mm: two curves closer than that touch.

The outline and holes may be drawn either way round. The region stores the outline anticlockwise and the holes clockwise, all in the geom.UCS of the outline, which is the UCS of the region. Assigning the region another UCS moves it there.

A geom.Region is a value: every change makes a new one.

See also: geom.Path, geom.Polyline, geom.Spline, geom.UCS, solid.extrude

Source Code: geom.Region

The geom.Region class contains the following properties:

The outline, a closed geom.Path running anticlockwise in the plane of its UCS, which is the plane of the region.

The holes, a row cell array of closed geom.Path objects running clockwise, in the UCS of the outline; empty when there are none.

The geom.UCS the outline and holes are coordinates in. Assigning another moves the region onto it, its shape unchanged in its own coordinates, so a region drawn in the xy plane is laid on the face of a part by assigning it the face’s UCS.

The geom.Region class offers the following public methods:

geom.Region: R = geom.Region (OUTLINE)

geom.Region: R = geom.Region (OUTLINE, HOLES)

R = geom.Region (OUTLINE) makes the area inside OUTLINE, a closed geom.Polyline, geom.Path or geom.Spline lying in the plane of its UCS.

R = geom.Region (OUTLINE, HOLES) cuts out of it the areas inside the closed polylines, paths and splines in the cell array HOLES. A hole given in another frame of the same plane is carried into the frame of the outline. The region keeps each as a geom.Path.

OUTLINE and each hole may also be given as the matrix of vertices a geom.Polyline is made from, [x, y, bulge] rows or [x, y] rows for straight segments. An outline given so lies in the xy plane, and a hole given so lies in the plane of the outline:

 
 ## A plate 60 by 40 with a bore of diameter 20 and two square holes
 R = geom.Region ([0, 0; 60, 0; 60, 40; 0, 40], ...
                  {[20, 20, 1; 40, 20, 1], ...
                   [4, 4; 10, 4; 10, 10; 4, 10], ...
                   [50, 30; 56, 30; 56, 36; 50, 36]});

A hole with a smooth outline is a closed spline:

 
 H = geom.Spline ([20, 15; 35, 12; 40, 25; 28, 35; 18, 28], ...
                  'Closed', true);
 R = geom.Region ([0, 0; 80, 0; 80, 50; 0, 50], {H});

An invalid region is refused with an error naming the outline or hole at fault.

geom.Region: R = fillet (R, RADIUS)

R = fillet (R, RADIUS) rounds every corner of the outline and of every hole where two straight segments meet, with an arc of radius RADIUS millimetres tangent to both, as geom.Path.fillet does: the outline’s corners and the inside corners of its holes alike. This is the rounded outline of a plate or a pocket, drawn before it is extruded, which is simpler and more exact than rounding the edges of the solid afterwards. Corners next to an arc or a spline are left as they are. To round only some corners, round the outline or a hole as a path and make the region again.

 
 ## A plate 60 by 40 with corners of radius 5 and a slot with sharp
 ## corners rounded to 1
 R = geom.Region ([0, 0; 60, 0; 60, 40; 0, 40], ...
                  {[20, 15; 40, 15; 40, 25; 20, 25]});
 S = solid.extrude (fillet (R, 1), 6);

See also: geom.Path.fillet

geom.Region: R = chamfer (R, D)

geom.Region: R = chamfer (R, [D1, D2])

geom.Region: R = chamfer (R, D, 'Angle', A)

R = chamfer (R, D) cuts every corner of the outline and of every hole where two straight segments meet, D millimetres back along both segments, as geom.Path.chamfer does. Two distances or a distance and an angle are taken as there, before and after each corner in the order the region stores its vertices: anticlockwise round the outline, clockwise round the holes. To cut only some corners, cut the outline or a hole as a path and make the region again.

See also: geom.Path.chamfer, geom.Region.fillet

geom.Region: R = fit (R)

geom.Region: R = fit (R, MODE)

geom.Region: R = fit (…, Name, Value, …)

R = fit (R) replaces the straight segments of the outline and the holes of R with as few lines and circular arcs as follow them within a tolerance, so that a region cut from a mesh, whose round bore is a polygon of facets and whose edges zigzag with the noise of a scan, becomes the outline it was drawn from: its edges straight, its bore a circle, its fillets arcs. Where two pieces meet without a corner they meet tangentially. Arcs and splines already in R are kept, and the straight segments between them fitted.

MODE chooses what the fit may use: 'lines', lines only; 'arcs', lines and arcs, the default; or 'curves', lines, arcs that turn at least 60 degrees, lines at least a fiftieth of the region’s size, and smooth cubic splines for the stretches between them, the shape of a free-form part.

Name/Value pairs:

'AbsTol'
The furthest, in millimetres, the fit may stray from the segments it replaces, and they from it.
'RelTol'
The same as a fraction of the region’s size, the diagonal of the box around its outline. Given alone, either tolerance holds alone; given both, the stricter. The default is a 'RelTol' of 1e-3. To turn a faceted bore into a circle the tolerance must be larger than its facets stray from the circle.
'Corner'
The turn, in degrees, at which the outline has a corner, 20 by default. The turn is measured on a sliding window: between the mean direction of the outline over a stretch behind a point and over a stretch ahead of it, so that noise and a small fillet saved as a few facets do not make corners of their own. A corner is kept only where the outline lies within the tolerance of the sharp corner its two sides make, which then sits where the sides meet; a larger fillet is fitted as an arc.
'Window'
The length of each stretch, in millimetres, ten tolerances by default.

The fitted region is checked as any region is. Should a fit make a loop cross or touch another, as when two lie closer than the tolerance, the region is fitted again at half the tolerance, up to four times, and returned as it was when it never passes.

 
 ## A slice of a scanned part, its bore a circle again
 M = polymesh.read ('part.stl');
 R = section (M, geom.UCS ([0, 0, 1], [0, 0, 5]));
 R = fit (R{1}, 'arcs', 'AbsTol', 0.01);

See also: polymesh.Mesh.section, geom.Region.fillet, geom.Spline

geom.Region: R = union (R1, R2, …)

R = union (R1, R2, …) returns the area covered by any of the regions, as a 1-by-N cell array of geom.Region objects, one for each separate piece, largest first, in the geom.UCS of R1. Each argument is a region or a cell array of them, such as another of these operations returns, so that they chain. Every region must lie in the plane of the first. Where two meet along an edge they become one, and the edges of the result are those of the regions, arcs and splines exact. This is OpenSCAD’s union of 2-D shapes, before the result is extruded or revolved.

 
 ## A plate and a tab, as one outline
 R = union (geom.Region ([0, 0; 60, 0; 60, 40; 0, 40]), ...
            geom.Region ([50, 10; 80, 10; 80, 30; 50, 30]));
 S = solid.extrude (R{1}, 5);

See also: geom.Region.subtract, geom.Region.intersect, geom.Region.offset

geom.Region: R = subtract (R1, R2, …)

R = subtract (R1, R2, …) returns the area of R1 that lies in none of the regions after it, as geom.Region.union returns its result: a cell array of regions, largest first, in the geom.UCS of R1, empty when nothing is left. This is OpenSCAD’s difference of 2-D shapes.

See also: geom.Region.union, geom.Region.intersect

geom.Region: R = intersect (R1, R2, …)

R = intersect (R1, R2, …) returns the area that lies in every one of the regions, as geom.Region.union returns its result, empty when they share none. This is OpenSCAD’s intersection of 2-D shapes.

See also: geom.Region.union, geom.Region.subtract

geom.Region: R = offset (R, D)

geom.Region: R = offset (R, D, 'Corners', C)

R = offset (R, D) returns the points of the plane that lie within D millimetres of the region, for a positive D, or the points of the region at least -D inside its edges, for a negative one: the outline moves out by D and the holes close in by it, or the other way. The corners that come out of the move are round by default, arcs of radius D, as OpenSCAD’s offset (r = D) makes them. Shrinking can split a region into pieces or leave nothing, so the result is a cell array of regions as geom.Region.union returns it.

With 'Corners' set to 'sharp' the edges are carried on to meet, as offset (delta = D) makes them, and with 'chamfer' each such corner between straight edges is cut off square to the corner, D from where it was, as offset (delta = D, chamfer = true) does.

The edges of the result are those of the region moved, straight edges straight and arcs exact; a spline’s offset is a spline that Open CASCADE fits to it, to about a part in ten million.

 
 ## A band 2 wide round a flange, G{1}; G{2} is the band 2 wide
 ## inside its bore, which grows into it too
 F = geom.Region ([0, 0; 60, 0; 60, 40; 0, 40], ...
                  {[30, 20, 1; 40, 20, 1]});
 G = subtract (offset (F, 2), F);

See also: geom.Region.union, geom.Region.fillet, geom.offset

geom.Region: R = hull (R1, R2, …)

R = hull (R1, R2, …) returns the smallest convex region that holds every region and point given, the shape a band stretched round them takes, as a geom.Region in the geom.UCS of R1. Each argument after the first is a region, a cell array of regions, such as geom.Region.union returns, or an N-by-2 matrix of points in the coordinates of that UCS. Every region must lie in the plane of the first; only outlines count, since a hole cannot reach the hull.

The hull is exact where the regions are made of lines and arcs: where it passes from one to the next its edge is a straight line truly tangent to the arcs it leaves and meets, and where an arc reaches furthest the hull follows the arc. This is OpenSCAD’s hull of 2-D shapes, which there are polygons of facets: the outline of a lever from the circles at its ends, of a bracket from its bosses, or of a plate rounded from four circles. A spline is taken as points along it, the curve turning a tenth of a degree from one to the next.

 
 ## A lever: bosses of radius 10 and 5, 40 apart, and its bores
 C = @(x, r) geom.Region ([x - r, 0, 1; x + r, 0, 1]);
 L = hull (C (0, 10), C (40, 5));
 L = subtract (L, C (0, 5), C (40, 2.5));

It is computed without Open CASCADE.

See also: geom.Region.union, geom.Region.offset

geom.Region: R = resize (R, SZ)

geom.Region: R = resize (R, SZ, 'Uniform', TF)

R = resize (R, SZ) scales the region evenly so that the box round it is as large as it can be within the sizes SZ = [x, y], in millimetres along the axes of its UCS; a size of 0 leaves that direction free. resize (R, [30, 0]) makes the region 30 wide and keeps its proportions. The corner of the box at the least x and y stays where it is, and arcs stay arcs.

With 'Uniform' set to false each direction given is scaled to its size on its own and a direction left at 0 keeps its size, as OpenSCAD’s resize does. An arc stretched so becomes part of an ellipse, kept exactly as a rational geom.Spline.

 
 ## A disc of diameter 10 stretched into an ellipse 40 by 20
 E = resize (geom.Region ([-5, 0, 1; 5, 0, 1]), [40, 20], ...
             'Uniform', false);

See also: geom.Region.mirror, solid.Shape.resize

geom.Region: R = mirror (R, N)

geom.Region: R = mirror (R, N, P)

R = mirror (R, N, P) reflects the region in the line through the point P, the origin of its UCS by default, square to the nonzero direction N, both 2-element vectors in its UCS. mirror (R, [1, 0]) reflects in the y axis. Only the reflection is returned; union (R, mirror (R, …)) keeps both, as a profile drawn for one side of a symmetric part is made whole.

See also: geom.Region.union, solid.Shape.mirror

geom.Region: C = copy (R, D)

C = copy (R, D) places a copy of the region moved by each row of D, an N-by-2 matrix of offsets in its UCS, and returns their union as geom.Region.union returns it, a cell array of regions, largest first. The region itself is among them only where a row of D is zero. Copies that overlap become one region.

See also: geom.Region.rectarray, geom.Region.polararray, solid.Shape.copy

geom.Region: C = rectarray (R, COUNT, SPACING)

C = rectarray (R, COUNT, SPACING) places COUNT = [nx, ny] copies of the region along the x and y axes of its UCS, SPACING = [dx, dy] millimetres apart, the first where the region is; a negative spacing runs the other way. It returns their union as geom.Region.copy does. This is a grid of holes or slots, drawn once and subtracted from a plate in one step.

 
 ## A plate with four rows of six holes of diameter 4, 10 apart
 H = rectarray (geom.Region ([8, 10, 1; 12, 10, 1]), [6, 4], [10, 10]);
 P = subtract (geom.Region ([0, 0; 70, 0; 70, 50; 0, 50]), H);

See also: geom.Region.copy, geom.Region.polararray

geom.Region: C = polararray (R, N, ANGLE)

geom.Region: C = polararray (R, N, ANGLE, P)

geom.Region: C = polararray (…, 'Rotate', TF)

C = polararray (R, N, ANGLE, P) places N copies of the region round the point P of its plane, the origin of its UCS by default, the first where the region is and the rest turned on anticlockwise, clockwise for a negative ANGLE. A whole turn, ANGLE of 360, spaces them evenly ANGLE / N apart; a part of a turn puts one at each end, ANGLE / (N - 1) apart. It returns their union as geom.Region.copy does.

Each copy is turned as it goes round, as the holes of a bolt circle or the spokes of a wheel are. With 'Rotate' set to false each copy keeps the region’s own direction, moved as the centre of the box round it moves.

 
 ## A flange of diameter 60 with a bore of 20 and six bolt holes of 6
 ## on a circle of 40
 H = polararray (geom.Region ([17, 0, 1; 23, 0, 1]), 6, 360);
 F = subtract (geom.Region ([-30, 0, 1; 30, 0, 1], ...
                           {[-10, 0, 1; 10, 0, 1]}), H);

See also: geom.Region.copy, geom.Region.rectarray

geom.Region: write (R, FILE)

geom.Region: write (R, FILE, Name, Value, …)

write (R, FILE) writes the region R to FILE, which must end in .dxf, as its loops in an ASCII DXF drawing, the outline first and then the holes, bound by a group: a loop of straight segments and arcs is one closed LWPOLYLINE on the region’s plane, a loop with a spline in it its pieces. The group’s extended data, under the application 'DRAFTING', names the class and holds the region’s geom.UCS, so geom.read gives back the region that was written, its holes and frame included.

Name/Value pairs:

'Layer'
The layer, '0' by default.
'Linetype'
One of the line types of draw.linetype, or any name the receiving program holds; 'CONTINUOUS' by default.
'Colour'
An AutoCAD colour index from 1 to 256, 256 meaning the layer’s colour, which is the default. True colour came only with R2004.
'Fill'
true adds a solid HATCH over the region, written with its group, so it reads back as part of the region rather than as a second one; false by default.
'Version'
'R2000' (AC1015), the default, or 'R12' (AC1009) for a program that reads nothing later. R12 has no groups and no HATCH, so a region is an error there.
'LTScale'
The drawing’s line-type scale, 1 by default, written in the header so the dashes look the same wherever the file is opened.

The drawing units are millimetres. Several geom objects go in one file through geom.write.

See also: geom.read, geom.write, draw.Drawing.write

geom.Region: R = geom.Region.nest (LOOPS)

R = geom.Region.nest (LOOPS) takes the closed geom.Path, geom.Polyline and geom.Spline objects in the cell array LOOPS, in any order, and returns the regions they bound as a row cell array, largest first, or cell (1, 0) when LOOPS is empty. This is how the outlines of a drawing, an outline and the bores and slots drawn inside it, become regions to make solids from.

Loops nest only with loops in the same plane. In a plane, a loop that no other loop encloses is the outline of a region, and a loop inside it is a hole in that region. A loop inside a hole is an island: it is the outline of a region of its own, with any loops inside it as its holes, and so on inwards, since a region is one outline and its holes. Each region is in the UCS of the first loop of its plane in LOOPS, and, as every region does, runs its outline anticlockwise and its holes clockwise.

A loop given in world coordinates need not lie in the plane of its UCS; it must lie in a plane. Loops that cross or touch, themselves or each other, make no regions and are refused.

 
 ## A plate with a bore, and a disc lying in the bore
 R = geom.Region.nest ({geom.Polyline ([20, 20, 1; 40, 20, 1], ...
                                        'Closed', true), ...
                       geom.Polyline ([0, 0; 60, 0; 60, 40; 0, 40], ...
                                      'Closed', true), ...
                       geom.Polyline ([25, 20, 1; 35, 20, 1], ...
                                      'Closed', true)});

See also: geom.Path.chain, geom.Region