Overview

The slicing functions are used to slice and fill planar slices of meshes. This can be used in programming CAM algorithms, and other geomemtric analysis.

RoseMesh * mesh;

RoseReal2DArray loops;
RoseReal2DArray infill;
RoseXform plane;

/* A point the the plane we are slicing */ct
RosePoint origin(0,0,12.);

/* Compute a set of loops throug a plane at z=12, rotated 15 degrees */
rose_slice_plane_2d(
    loops, plane, mesh, origin, 15, roseunit_deg);

/* Create a series of horizontal lines inside the loops */
rose_slice_fill_loops(infill, loops, space);

/* Sort the lines to minimize the distance between them */
rose_slice_sort_segs_2d(infill);

/* Print out the loops and infill lines, as a polyline with a blank line
 * splitting the polys.
 */
printf (=======\n);

FILE * out = stdout;
if (outfile)
    out = fopen(outfile, w);

for (i=0, sz=loops.size(); i<sz; i++) {
    const RosePoint2D & pt = loops.as_point(i);
    if (pt.x() == ROSE_NULL_REAL) {
	fprintf (out, \n);
	continue;
    }
    RosePoint p3d;
    xform_apply(p3d, plane, pt);	
    fprintf (out, %g %g %g\n, p3d.x(), p3d.y(), p3d.z());
}

fprintf (out, \n);

for (i=0, sz=infill.size(); i<sz; i+=2) {
    const RosePoint2D & pt_a = infill.as_point(i);
    const RosePoint2D & pt_b = infill.as_point(i+1);

    RosePoint pt3d_a, pt3d_b;

    xform_apply(pt3d_a, plane, pt_a);
    xform_apply(pt3d_b, plane, pt_b);

    fprintf (out, %g %g %g\n,
	    pt3d_a.x(),pt3d_a.y(),pt3d_a.z());
    fprintf (out, %g %g %g\n,
	    pt3d_b.x(),pt3d_b.y(),pt3d_b.z());
    fprintf (out, \n);
}

rose_slice_fill_loops()

void rose_slice_fill_loops(
	RoseReal2DArray & infill,
	const RoseReal2DArray & loops,
	double space,
	double tol = ROSE_NULL_REAL
	);

void rose_slice_fill_loops(
	RoseReal2DArray & infill,
	const RoseReal2DArray & loops,
	const RoseBoundingBox2D & patch,
	double space,
	double rot_angle,
	RoseUnit rot_unit = roseunit_rad,
	double tol = ROSE_NULL_REAL
	);

The rose_slice_fill_loops() function computes a set of line segments in 2D that intersect the loops.

The function takes the following parameters:

infill
Returned segments. Each pair of points in the list defines the begin and end point of a segment.
loops
A 2D polylinline of the loops. This can be obtained from rose_mesh_slice_plane_2d(). The last point in each loop should repeat the first. Loops are seperated by the NULL value (ROSE_NULL_REAL,ROSE_NULL_REAL)
space
Distance between lines.
rot_angle
The rotation of the fill lines. (0 is horizontal, otherwise this specified a counter clockwise rotation of the lines.
rot_unit
The unit for rotation. This will generally be degrees (roseunint_deg) or the default, radians (roseunit_rad).
patch
A 2D bounding box that all the lines are clipped to. This allows for multiple patches with different rotations to be generated on a single loop.
tol
Distance tolerance between points.

rose_slice_get_loop_isects()

void rose_slice_get_loop_isects(
	rose_real_vector & params,
	const RoseReal2DArray & loops,
	const RosePoint2D & p1,
	const RosePoint2D & p2,
	double tol = ROSE_NULL_REAL
	);

The rose_slice_get_loop_isects() function computes the intersections between a line segment and a set of loops in 2D. The intersections are returned as a set of parameters of the line segment, where the line is defined as the vector function:

f(t) = p1 + t*(p2-p1)

rose_slice_plane()

int rose_slice_plane(
	RoseReal3DArray & retloops,
	const RoseMesh * mesh,
	const RoseXform & plane,
	double tol = ROSE_NULL_REAL
	);

int rose_slice_plane(
	RoseReal3DArray & retloops,
	const RoseMesh * mesh,
	const RosePoint & loc,
	const RoseDirection & normal
	);

int rose_slice_plane(
	RoseReal3DArray & retloops,
	const RoseMesh * mesh,
	const RosePoint & loc
	);

int rose_slice_plane(
	RoseReal3DArray & retloops,
	const RoseMesh * mesh,
	const double loc[3],
	const double normal[3]
	);

int rose_slice_plane(
	RoseReal3DArray & retloops,
	const RoseMesh * mesh,
	const double loc[3]
	);

The rose_mesh_slice_plane() functions compute the intersection between a mesh and a plane. The plane can be specified in various ways: a RoseXform, or a point on the plane, and optionally a plane normal. If the normal is not specified, the the normal is the Z direction (0,0,1).

The retloops parameter holds a polyline that defines the intersection points. If the intersection contains a closed loop, the last point in the loop will be equal to the first. If there are multiple, discontiguous, loops, then a special NULL point is used to split them (ROSE_NULL_REAL, ROSE_NULL_REAL, ROSE_NULL_REAL)

The following code will get a set of loops, and print the intersection loop, with a blank between disjoint loops.

RoseReal3DArray loops;

rose_mesh_slice_plane(loops, mesh, origin, normal);

printf (=======\n);

for (i=0, sz=loops.size(); i<sz; i++) {
    const RosePoint & pt = loops.as_point(i);
    if (pt.x() == ROSE_NULL_REAL) {
	/* Break in loop, print a blank line */
	printf (\n);
	continue;
    }
    printf (%g %g %g\n, pt.x(), pt.y(), pt.z());
}

rose_slice_plane_2d()

int rose_slice_plane_2d(
	RoseReal2DArray & retloops_2d,
	RoseXform & xform,
	const RoseMesh * mesh,
	const RosePoint & loc,
	const RoseDirection & normal,
	double rot_angle,
	RoseUnit rot_unit = roseunit_rad,
	double tol = ROSE_NULL_REAL
	);

int rose_slice_plane_2d(
	RoseReal2DArray & retloops_2d,
	RoseXform & xform,
	const RoseMesh * mesh,
	const RosePoint & loc,
	double rot_angle,
	RoseUnit rot_unit = roseunit_rad
	); 

int rose_slice_plane_2d(
	RoseReal2DArray & retloops_2d,
	RoseXform & xform,
	const RoseMesh * mesh,
	const double loc[3],
	double rot_angle,
	RoseUnit rot_unit = roseunit_rad
	); 

The rose_slice_plane_2d() function compute the intersection of a plane and a shell, but return the loops in a 2D space. The xform parameter can be used to convert the 2D value back to 3D. By working in 2D, is is easier to compute line-line intersections.

The plane is returned in the xform parameter. This xform can be used to convert a value back to 3D, as follows:

void cvt_to_3d (
   RosePoint & p3d,
   const RoseXform & xform,
   const RosePoint & p2d
   )
{
    RosePoint tmp(p2d.x(), p2d.y(), 0.);  /* initialize 3D point with Z at zero */
    rose_xform_apply(p3d, xform, tmp);  /* apply xform */
}

The rot_angle and rot_unit give an angle about the plane normal to rotate the plane. This will not effect the location of the intersection point in 3D, but will change the parameterization of the plane in 2D. This is used so that infill can be computed as horizontal and vertical lines (in 2D) regardless of the plane orientation, which simplifies some CAM algorithims.

rose_slice_sort_segs_2d()

void rose_slice_sort_segs_2d(RoseReal2DArray & segs);

Take a set of segments (as produced by rose_mesh_fill_loops, and reorder them to minimize the distance between segments. This function may reverse the order of a segment, if that will produce a better result.