Package org.bzdev.p3d

Class Model3D

java.lang.Object
org.bzdev.p3d.Model3D
All Implemented Interfaces:
Shape3D, Model3DOps<Model3D.Triangle>

public class Model3D extends Object implements Shape3D, Model3DOps<Model3D.Triangle>
Three-dimensional model class. This class represents a 3D model of an object as a set of triangles. It can produce an STL file, which is commonly supported by 3D printers.

As an example of its use, the statements


 Model3D m3d = new Model3D();
 m3d.setStackTraceMode(true);
 m3d.addTriangle(...);
 ...
 m3d.addTriangle(...);
 if (m3d.notPrintable(System.out)) System.exit(1);
 m3d.writeSTL("model test", "model.stl");
 System.exit(0);
 
will create a model, test it to verify that it is printable on a 3D printer, and if it is printable, create an STL file. The call to setStackTraceMode will configure the model so that each triangle the model creates with an explicitly specified tag is tagged with a stack trace created when the triangle was created. Please see setStackTraceMode(boolean) for the procedure for setting this permission when the scrunner command is used to run a script.

The triangles in a model are expected to follow the same rules used by STL files: the right-hand rule determines the triangle's orientation and an edge of a triangle must intersect another triangle at a vertex. While one can create triangles explicitly, one can also add the objects in another instance of Model3D.

The simplest way to create an image showing the model is to use the method createImageSequence(OutputStream,String,int,int):


  Model3D m3d = new Model3D();
  ...
  m3d.addTriangle(...);
  ...
  m3d.createImageSequence(new FileOutputStream("model.isq"), "png", 8, 4);
 

The file model.isq is a ZIP file with a manifest describing various image parameters, and a with a sequence of image files showing the model in various orientations.

The following code creates an image, using the* low-level API:


 int WIDTH = 800;
 int HEIGHT = 800;
 ...
 Model3D m3d = new Model3D();
 ...
 m3d.addTriangle(...);
 ...
 Model3D.Image image =
    new Model3D.Image(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB_PRE);
 image.setCoordRotation(...);
 image.setBacksideColor(Color.RED);
 image.setEdgeColor(Color.GREEN);
 Graphics2D g2d = image.createGraphics();
 g2d.setColor(Color.BLUE);
 g2d.fillRect(0, 0, WIDTH, HEIGHT);
 g2d.dispose();
 m3d.setImageParameters(image);
 m3d.render(image);
 image.write("png", "modeltest.png");
 

To create an animation showing the model from different orientations use the following code:


 Model3D m3d = new Model3D();
 ...
 m3d.addTriangle(...);
 ...
 Animation2D a2d = new Animation2D(...);
 a2d.setBackgroundColor(Color.BLUE.dargker().darker());
 Model3DViewFactory = new Model3DViewFactory(a2d);
 factory.setModel(m3d);
 // configure factory
 ...
 factory.createObject(view);
 // clear directory tmp
 ...
 int maxframes = a2d.estimateFrameCount(ANIMATION_LENGTH);
 a2d.initFrames(maxFrames, "tmp/img-", "png")
 a2d.scheduleFrames(0, maxframes);
 a2d.run();
 
The documentation for Model3DViewFactory describes how to configure this factory.

When a triangle is created, the coordinates of each vertex are rounded to the nearest single-precision floating-point number, but stored as a double-precision floating-point number. In addition, any value that differs from 0 by less than one part in 1010 will be treated as 0.0. This is done for two reasons:

  1. to prevent round-off errors from turning what should be a common vertex for multiple triangles into multiple vertices.
  2. So that area and volume computations will use the coordinates of vertices as those would be stored in an STL file.
Although an STL file can contain a normal vector for a triangle, the models create the normal vector from the vertices directly: the computed vector is more accurate.

Two types of transformations can be applied when a model is being created:

  • One may call pushParms(), followed by setObjectTranslation, setObjectTranslation, and setObjectRotation in order to change the position and orientation the triangles that will be created. This is intended for the case where an object needs to have a particular orientation to be printed or when multiple copies of the object are needed.
  • One may call pushTransform(Transform3D) to modify an object. The transform can be an arbitrary one. For example, one could create a set of triangles that represents a disk, increase its height with increasing radius, and then stretch that object in the Y direction in order to create an elliptical bowl.
Calls to popParms() and popTransform() will remove the transforms that were created, leaving the ones previously in place.

Because Model3D was designed for 3D printing, coordinate values are rounded to single-precision floating point numbers and very small values (those with absolute values less than the value produced by the Java expression Math.ulp(1.0F)) are rounded to 0.0. This rounding is not performed by Surface3D and its subclasses.

Model3D provides several methods to aid in debugging. In particular,

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Class representing the edge of a triangle in a 3 dimensional space.
    static class 
    Image for a 3D model.
    static interface 
    Data used by a Model3D.Image instance to render an instance of Model3D.
    static class 
    The implementation of ImageData used by Model3D.
    static class 
    Image Parameters Instances of Image.ImageParams are created by the methods setImageParameters(m3d), setImageParameters(m3d, border), setImageParameters(m3d, border magnification), and * setImageParameters.
    class 
    Class representing a straight line segment in 3 dimensions.
    static class 
    Class to represent multiple tags (a current tag and a history)
    static class 
    Exception indicating that an error occurred while tessellating a model.
    static class 
    Class representing a triangle embedded in a 3 dimensional space.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Constructor.
    Model3D(boolean strict)
    Constructor specifying strict mode.
  • Method Summary

    Modifier and Type
    Method
    Description
    addFlippedTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3)
    Add a flipped triangle to the model, specifying the triangle by its vertices.
    addFlippedTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color)
    Add a flipped triangle to the model, specifying the triangle by its vertices and color.
    addFlippedTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color, Object tag)
    Add a flipped triangle to the model, specifying the triangle by its vertices and color, also specifying a tag.
    addLineSegment(double x1, double y1, double z1, double x2, double y2, double z2)
    Add a line segment given the coordinates of its end points.
    addLineSegment(double x1, double y1, double z1, double x2, double y2, double z2, Color color)
    Add a line segment given the coordinates of its end points and color.
    addLineSegment(double x1, double y1, double z1, double x2, double y2, double z2, Color color, Object tag)
    Add a line segment given the coordinates of its end points, its color, and a tag.
    Add a line segment.
    void
    Add the objects in another Model3D to this model.
    void
    Add a generalized model.
    void
    addModel(Model3DOps<?> m3d, Object tag)
    Add a generalized model, including a tag.
    void
    addModel(Model3D m3d, boolean tessellate)
    Add a possibly tessellated 3D model to this model.
    void
    addModel(Model3D m3d, Object tag)
    Add the objects in another Model3D to this model and tag them.
    addTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3)
    Add a triangle to the model, specifying the triangle by its vertices.
    addTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color)
    Add a triangle to the model, specifying the triangle by its vertices and its color.
    addTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color, Object tag)
    Add a triangle to the model, specifying the triangle by its vertices and its color, also specifying a tag.
    Add a triangle to the model.
    final void
    append(Shape3D surface)
    Append the surface segments specified by another surface.
    final void
    append(Shape3D surface, Transform3D transform)
    Append the surface segments specified by another surface after applying a transformation.
    final void
    Append the surface segments specified by a surface iterator.
    double
    Compute the surface area of a 3D model The model must be a closed manifold embedded in a two-dimensional space.
    void
    createCrossSection(Graph graph, double xp, double yp, double zp, double[] normal)
    Generate a graph containing a cross section of this model, using the current tessellation level, where triangle edges pass through a plane that passes through the point (xp, yp, zp) and perpendicular to a normal vector.
    void
    createImageSequence(OutputStream os, String imageType, int nphi, int ntheta)
    Create a sequence of images.
    void
    createImageSequence(OutputStream os, String imageType, int nphi, int ntheta, double delta, double colorFactor)
    Create a sequence of images, specifying a color factor and the maximum triangle size for rendering.
    void
    createImageSequence(OutputStream os, String imageType, int nphi, int ntheta, double delta, double colorFactor, double normalFactor, boolean showEdges)
    Create a sequence of images, specifying a color factor, normal factor and the maximum triangle size for rendering.
    double
    Find the minimum ratio of the separation between adjacent coordinate values to the ULP value for those coordinates, treated as single-precision values.
    Get the boundary for this Shape3D.
    double
    Get the length parallel to the x axis for the bounding box of containing all objects.
    double
    Get the length parallel to the y axis for the bounding box of containing all objects.
    double
    Get the length parallel to the z axis for the bounding box of containing all objects.
    Get a bounding rectangular cuboid for a 3D shape.
    getComponent(int index)
    Get a manifold component.
    double
    Get the minimum y coordinate for all objects contained in a 3D model.
    double
    Get the maximum x coordinate for all objects contained in a 3D model.
    double
    Get the maximum z coordinate for all objects contained in a 3D model.
    double
    Get the minimum x coordinate for all objects contained in a 3D model.
    double
    Get the minimum z coordinate for all objects contained in a 3D model.
    double
    Get the maximum y coordinate for all objects contained in a 3D model.
    boolean
    Get the current stack-trace mode.
    Get a surface iterator for this Shape3D.
    getSurfaceIterator(Transform3D tform, int level)
    Get a surface iterator for this Shape3D, subdividing the surface.
    int
    Get the current tessellation level.
    double
    Get the unit scale factor for X3D files.
    boolean
    Determine if this Shape3D is a closed two-dimensional manifold.
    boolean
    isComponentHollow(int index)
    Determine if a component of a 3D model is hollow.
    boolean
    Determine if a surface is oriented.
    boolean
    Determine if some manifold component represents a vacant space.
    boolean
    Determine if some manifold component represents a vacant space and optionally store a record of the results.
    boolean
    Test if a model is not printable on a 3D printer..
    boolean
    notPrintable(boolean hollow)
    Test if a model is not printable on a 3D printer, specifying whether hollow objects are allowed.
    boolean
    notPrintable(boolean hollow, Appendable out)
    Test if a model is not printable on a 3D printer, given an Appendable for error-message output and specifying whether hollow objects are allowed.
    boolean
    Test if a model is not printable on a 3D printer, given an Appendable for error-message output.
    int
    Get the number of manifold components for a model.
    void
    Pop object-transformation parameters.
    void
    Remove the last transform that was added.
    boolean
    Test if a model is printable on a 3D printer..
    boolean
    printable(boolean hollow)
    Test if a model is printable on a 3D printer, specifying whether hollow objects are allowed.
    boolean
    printable(boolean hollow, Appendable out)
    Test if a model is printable on a 3D printer, given an Appendable for error-message output and specifying whether hollow objects are allowed.
    boolean
    Test if a model is printable on a 3D printer, given an Appendable for error-message output.
    void
    Push object-transformation parameters.
    void
    Add a transform that will be applied to a triangle when it is added to the model.
    void
    Remove a line segment.
    void
    Remove a triangle.
    void
    Render a model.
    void
    Render a model given a graphics context.
    void
    render(Model3D.ImageData id, Graphics2D g2d, boolean keep)
    Render a model given a graphics context and a render-list preservation flag.
    void
    render(Model3D.ImageData id, Graphics2D g2d, boolean keep, double tx, double ty)
    Render a model given a graphics context and translations.
    void
    render(Model3D.Image image, boolean keep)
    Render a model, optionally preserving the render list so that additional objects can be added.
    void
    render(Model3D.Image image, boolean keep, double tx, double ty)
    Render a model, optionally preserving the render list so that additional objects can be added and translating the coordinate system for the model.
    Set image parameters.
    setImageParameters(Model3D.ImageData idata, double border)
    Set image parameters given a border.
    setImageParameters(Model3D.ImageData idata, double border, double magnification)
    Set image parameters given a border and magnification.
    setImageParameters(Model3D.ImageData idata, double magnification, double xfract, double yfract)
    Set image parameters given a magnification and fractional positions.
    setImageParameters(Model3D.ImageData id, double border, double magnification, double xfract, double yfract)
    Set image parameters given a border, magnification, and fractional positions.
    setImageParameters(Model3D.ImageData id, double border, double magnification, double xfract, double yfract, boolean changeScale)
    Set image parameters given a border, magnification, fractional positions, and a scaling option The image data (id) will be modified based on the other arguments.
    void
    setObjectRotation(double phi, double theta, double psi)
    Rotate new objects.
    void
    setObjectTranslation(double x2, double y2, double z2)
    Specify how to Translate new objects after rotating them about (0,0,0).
    void
    setObjectTranslation(double x1, double y1, double z1, double x2, double y2, double z2)
    Specify how to Translate an object after rotating it about a point.
    void
    setStackTraceMode(boolean mode)
    Set stack-trace mode.
    void
    Set the value of STL Base to a default.
    void
    setSTLBase(boolean value)
    Set whether or not an STL base is used.
    void
    setSTLBase(double offset)
    Set the value of STL Base.
    void
    Set the tessellation level of this model.
    void
    setULPFactor(double ulpFactor)
    Set the ULP factor for this model.
    void
    setUnitScaleX3D(double value)
    Set the unit scale factor for X3D files.
    int
    Return the number of triangles and cubic patches in a model.
    Get an iterator that will return a sequence of triangles after tessellation using the preset tessellation level
    tessellate(int level)
    Get an iterator that will return a sequence of triangles after tessellation.
    Get a scanner that can iterate over the planar triangles provided by this model.
    Get a collection scanner that can iterate over planar triangles, Bézier triangles, and Bézier patches.
    Test that the model consists of a closed 2D manifold.
    Test that the model's 2D manifold is embedded in a Euclidean 3 dimensional space.
    Test that the model's 2D manifold is embedded in a Euclidean 3 dimensional space, setting a test limit.
    boolean
    Test that the model compoents are properly nested.
    boolean
    Test that the model compoents are properly nested, and record errors.
    double
    Compute the volume of a 3D model The model must be a closed manifold embedded in a two-dimensional space.
    void
    Create an STL file from the model, given a file.
    void
    Create an STL file from the model, given an output stream.
    void
    writeSTL(String id, String fname)
    Create an STL file from the model, given a file name.
    void
    Create an STL file from the model, given a writable byte channel.
    void
    writeX3D(String title, String description, String creator, boolean full, File f)
    Create an X3D file from the model, given a File and specifying a profile.
    void
    writeX3D(String title, String description, String creator, boolean full, OutputStream os)
    Create an X3D file from the model, specifying a profile and given an output stream.
    void
    writeX3D(String title, String description, String creator, boolean full, OutputStream os, boolean compress)
    Create an X3D file in either binary or XML format from the model, given a profile specification and an output stream.
    void
    writeX3D(String title, String description, String creator, boolean full, String fname)
    Create an X3D file from the model, given a file name and specifying a profile.
    void
    writeX3D(String title, String description, String creator, File f)
    Create an X3D file from the model, given a File.
    void
    writeX3D(String title, String description, String creator, OutputStream os)
    Create an X3D file from the model, given an output stream.
    void
    writeX3D(String title, String description, String creator, OutputStream os, boolean compress)
    Create an X3D file in either binary or XML format from the model, given an output stream.
    void
    writeX3D(String title, String description, String creator, String fname)
    Create an X3D file from the model, given a file name.
    double[]
    xbracket(double x)
    Find the values allowed for tessellation that bracket a given value for an X coordinate.
    double[]
    ybracket(double y)
    Find the values allowed for tessellation that bracket a given value for a Y coordinate.
    double[]
    zbracket(double z)
    Find the values allowed for tessellation that bracket a given value for a Z coordinate.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface org.bzdev.geom.Shape3D

    getBoundary
  • Constructor Details

    • Model3D

      public Model3D()
      Constructor.
    • Model3D

      public Model3D(boolean strict)
      Constructor specifying strict mode. Strict mode (the default) requires that tests for printability require that all surfaces in a model are closed two-dimensional manifolds. When strict mode is not active, an even number of triangles can share a common edge, provided the orientations of the triangles alternate during a rotation about the common edge, switching between a clockwise and counterclockwise direction. An example is two "towers" with a triangular cross section that meet at a common edge and that share a common base:
                *-----*
                 \   /
                  \ /
                   *
                  / \
                 /   \
                *-----*
       
      If the common vertices were split into pairs, and offset by a small distance δ, the surface becomes a closed two-dimensional manifold. When δ = 0, the surface is not a closed two-dimensional manifold, but is still printable.
      Parameters:
      strict - true if strict mode is used; false otherwise
      See Also:
  • Method Details

    • xbracket

      public double[] xbracket(double x)
      Find the values allowed for tessellation that bracket a given value for an X coordinate. If setULPFactor(double) was not called or was called with a value of 0.0, the value returned will contain the constants -&infty; and &infty; (Double.NEGATIVE_INFINITY and Double.POSITIVE_INFINITY respectively) and will contain one of these if the value of x is above or below the values previously provided when segments were added to the model.

      This method is provided for debugging.

      Parameters:
      x - the value of an X coordinate
      Returns:
      an array consisting of the X coordinate below or equal to x and the X coordinate above or equal to x.
    • ybracket

      public double[] ybracket(double y)
      Find the values allowed for tessellation that bracket a given value for a Y coordinate. If setULPFactor(double) was not called or was called with a value of 0.0, the value returned will contain the constants -&infty; and &infty; (Double.NEGATIVE_INFINITY and Double.POSITIVE_INFINITY respectively) and will contain one of these if the value of y is above or below the values previously provided when segments were added to the model.

      This method is provided for debugging.

      Parameters:
      y - the value of a Y coordinate
      Returns:
      an array consisting of the Y coordinate below or equal to x and the Y coordinate above or equal to x.
    • zbracket

      public double[] zbracket(double z)
      Find the values allowed for tessellation that bracket a given value for a Z coordinate. If setULPFactor(double) was not called or was called with a value of 0.0, the value returned will contain the constants -&infty; and &infty; (Double.NEGATIVE_INFINITY and Double.POSITIVE_INFINITY respectively) and will contain one of these if the value of z is above or below the values previously provided when segments were added to the model.

      This method is provided for debugging.

      Parameters:
      z - the value of a Z coordinate
      Returns:
      an array consisting of the Z coordinate below or equal to x and the Z coordinate above or equal to x.
    • findMinULPRatio

      public double findMinULPRatio()
      Find the minimum ratio of the separation between adjacent coordinate values to the ULP value for those coordinates, treated as single-precision values. The coordinates are obtained from tables maintained when setULPFactor(double) was called with a positive argument (such an argument's value must be at least 2.0). The value returned can be used as guide for adjusting the value returned by setULPFactor(double) by providing an estimate of the closest distance between vertices before tessellation. Values much larger than 1 are an indication that tessellation in not likely to be affected by roundoff errors (assuming setULPFactor(double) has been called with a non-zero argument).
      Returns:
      the minimum ratio of the separation between adjacent coordinate values to the ULP value for those coordinates, treated as single-precision values
    • setStackTraceMode

      public void setStackTraceMode(boolean mode)
      Set stack-trace mode. When stack-trace mode is on (true), triangles without an explicit tag are tagged with a stack trace taken at the point when the triangle was created. The default value is false.
      Parameters:
      mode - true to turn on stack-trace mode; false to turn it off
    • getStackTraceMode

      public boolean getStackTraceMode()
      Get the current stack-trace mode.
      Returns:
      the stack-trace mode
    • setTessellationLevel

      public void setTessellationLevel(int level)
      Set the tessellation level of this model. A value of 0 indicates no tessellation. Adding 1 to the level quadruples the number of triangles and patches.

      It is possible to make the value of level too high for particular models as double-precision values are converted to floats (the STL format uses floats). Some corner cases involving small floating-point errors can be handled by using the method setULPFactor(double) to coalesce nearby floating-point values.

      The initial tessellation level is 0. Checking if a model is printable, well-formed, etc., can take significantly longer if the level is set to values larger than 0. In cases where the time is excessive, one may want to check the model before calling this method. Similar considerations apply to generating images of a model using methods provided by this class. An alternative for high resolution images is to create an STL or X3D file and then use applications that make use of a computer's GPU to improve the performance.

      Parameters:
      level - the tessellation level
    • getTessellationLevel

      public int getTessellationLevel()
      Get the current tessellation level.
      Returns:
      the current tessellation level
    • pushParms

      public void pushParms()
      Push object-transformation parameters. These parameters are used to change the position or orientation of an object without modifying the code used to generate the object. The parameters set by the methods setObjectTranslation, setObjectTranslation, and setObjectRotation can be pushed onto a stack and later restored. The transformations are applied in order, with the most recently defined transformation applied first. This ordering supports the following use case:
      • A method m1() calls pushParms() adds an object to the model, and then sets the object translation and rotation multiple times to add additional objects to the model so that they are placed at specific locations relative to each other, creating a composite object.
      • A method m2() also calls PushParms() and sets the object rotation and translation to place a series of objects at specific locations relative to each other. These objects are copies of the composite object obtained by calling m1().
      Note that the relative positions of the objects created by a call to m1() is independent of whether m1() is called directly or if it is called by m2(). If the transformations were applied in the opposite order, this would in general not be the case.

      Object-transformations parameters are typically used when it is desirable to include multiple independent objects in a model and position them in a way that will take advantage of the pricing rules used by various 3D printing services.

      If pushTransform(Transform3D) is also used, the tranforms provided by that method are applied before any of the transforms set using setObjectTranslation, setObjectTranslation, and setObjectRotation

      See Also:
    • popParms

      public void popParms()
      Pop object-transformation parameters. This undoes the effect of the method pushParms().
      See Also:
    • setObjectTranslation

      public void setObjectTranslation(double x2, double y2, double z2)
      Specify how to Translate new objects after rotating them about (0,0,0). After the rotation, the point at the origin will be moved to point (x2, y2, z2). THis method is equivalent to calling setObjectTranslation(0.0, 0.0, 0.0,x2, y2, z2).

      There is a stack of transformations that includes rotations and translations. The transformations are applied in order, with the most recently defined transformation applied first. Pushing this stack saves the current translations and rotations.

      There is also a list of transforms set by calling pushTransform(Transform3D). Transforms on this list are applied before the object translations and rotations.

      Parameters:
      x2 - the x coordinate for the translation
      y2 - the y coordinate for the translation
      z2 - the z coordinate for the translation
      See Also:
    • setObjectTranslation

      public void setObjectTranslation(double x1, double y1, double z1, double x2, double y2, double z2)
      Specify how to Translate an object after rotating it about a point. after a rotation about the point (x1, y1, z1), the objects will be translated so that (x1, y1, z1) moves to (x2, y2, z2). There is a stack of transformations that includes rotations and translations. The transformations are applied in order, with the most recently defined transformation applied first. Pushing this stack saves the current translations and rotations.

      There is also a list of transforms set by calling pushTransform(Transform3D). Transforms on this list are applied before the object translations and rotations.

      Parameters:
      x1 - the initial x coordinate
      y1 - the initial y coordinate
      z1 - the initial z coordinate
      x2 - the final x coordinate
      y2 - the final y coordinate
      z2 - the final z coordinate
      See Also:
    • setObjectRotation

      public void setObjectRotation(double phi, double theta, double psi)
      Rotate new objects.

      The rotation is specified by Eulerian angles. The Eulerian angles follow the convention used in Goldstein, "Classical Mechanics" but the objects are rotated instead of the coordinates. The angle phi specifies an initial rotation of objects counterclockwise about the z-axis of an origin at (x1, y1, z1) set in the last call to setObjectTranslation(x1, y1, z1, x2, y2, z2), with a default of (0,0,0) for (x1,y1,z1) and (x2,y2,z2). The angle theta specifies a second rotation about an x axis through (x1, y1, z1), again counter clockwise. The angle psi specifies a final counterclockwise rotation about the z axis. The object is then translated so that the point at (x1, y1, z1) will be at (x2, y2, z2)

      In effect, the angles have the opposite signs from the corresponding angles used by setCoordRotation.

      There is a stack of transformations that includes rotations and translations. The transformations are applied in order, with the most recently defined transformation applied first. Pushing this stack saves the current translations and rotations.

      There is also a list of transforms set by calling pushTransform(Transform3D). Transforms on this list are applied before the object translations and rotations.

      Parameters:
      phi - the Eulerian angle phi in radians
      theta - the Eulerian angle theta in radians
      psi - the Eulerian angle psi in radians
    • getBoundingBoxX

      public double getBoundingBoxX()
      Get the length parallel to the x axis for the bounding box of containing all objects.
      Returns:
      the length of the bounding box in the x direction
    • getBoundingBoxY

      public double getBoundingBoxY()
      Get the length parallel to the y axis for the bounding box of containing all objects.
      Returns:
      the length of the bounding box in the y direction
    • getBoundingBoxZ

      public double getBoundingBoxZ()
      Get the length parallel to the z axis for the bounding box of containing all objects.
      Returns:
      the length of the bounding box in the z direction
    • getMinX

      public double getMinX()
      Get the minimum x coordinate for all objects contained in a 3D model.
      Returns:
      the minimum value of the x coordinate; Double.POSITIVE_INFINITY if the model is empty
    • getMaxX

      public double getMaxX()
      Get the minimum y coordinate for all objects contained in a 3D model.
      Returns:
      the minimum value of the y coordinate; Double.NEGATIVE_INFINITY if the model is empty
    • getMinY

      public double getMinY()
      Get the minimum z coordinate for all objects contained in a 3D model.
      Returns:
      the minimum value of the z coordinate; Double.POSITIVE_INFINITY if the model is empty.
    • getMaxY

      public double getMaxY()
      Get the maximum x coordinate for all objects contained in a 3D model.
      Returns:
      the maximum value of the x coordinate; Double.NEGATIVE_INFINITY if the model is empty.
    • getMinZ

      public double getMinZ()
      Get the maximum y coordinate for all objects contained in a 3D model.
      Returns:
      the maximum value of the y coordinate; Double.POSITIVE_INFINITY if the model is empty.
    • getMaxZ

      public double getMaxZ()
      Get the maximum z coordinate for all objects contained in a 3D model.
      Returns:
      the maximum value of the z coordinate; Double.NEGATIVE_INFINITY if the model is empty.
    • getBounds

      public Rectangle3D getBounds()
      Description copied from interface: Shape3D
      Get a bounding rectangular cuboid for a 3D shape. The edges will be aligned with the X, Y and Z axes. The cuboid created may not be the smallest one possible (for example, shapes defined by Bézier surfaces may just use the control points to determine the cuboid as the convex hull for the control points includes all of the surface for parameters in the normal range [0,1]).
      Specified by:
      getBounds in interface Shape3D
      Returns:
      a bounding rectangular cuboid for this Shape3D; null if the shape does not contain any points
    • getSurfaceIterator

      public SurfaceIterator getSurfaceIterator(Transform3D tform)
      Description copied from interface: Shape3D
      Get a surface iterator for this Shape3D. The surface iterator will represent the shape as a sequence of Bézier patches and Bézier triangles, with the order of the sequence arbitrary.

      Unless the transform is an affine transform, the transformation is not exact. In this case, the patches and triangles that constitute the surface should be small enough that the transform can be approximated by an affine transform over the region containing the control points.

      Specified by:
      getSurfaceIterator in interface Shape3D
      Parameters:
      tform - a transform to apply to each control point; null for the identity transform
      Returns:
      a surface iterator
    • getSurfaceIterator

      public SurfaceIterator getSurfaceIterator(Transform3D tform, int level)
      Description copied from interface: Shape3D
      Get a surface iterator for this Shape3D, subdividing the surface. The surface iterator will represent the shape as a sequence of Bézier patches and Bézier triangles, with the order of the sequence arbitrary.

      Unless the transform is an affine transform, the transformation is not exact. In this case, the patches and triangles that constitute the surface after each is subdivided should be small enough that the transform can be approximated by an affine transform over the region containing the control points.

      Specified by:
      getSurfaceIterator in interface Shape3D
      Parameters:
      tform - a transform to apply to each control point; null for the identity transform
      level - the number of levels of partitioning (each additional level splits the previous level into quarters)
      Returns:
      a surface iterator
    • isOriented

      public boolean isOriented()
      Description copied from interface: Shape3D
      Determine if a surface is oriented.
      Specified by:
      isOriented in interface Shape3D
      Returns:
      true if the surface has an orientation; false if it does not
    • getBoundary

      public Path3D getBoundary()
      Description copied from interface: Shape3D
      Get the boundary for this Shape3D. For a closed surface, the boundary will be an empty path.

      Typically, a boundary will consist of a series of distinct closed subpaths. Subpaths are separated by segments whose type is {link PathIterator3D#SEG_MOVETO}. For a closed manifold, the boundary will be an empty path.

      Specified by:
      getBoundary in interface Shape3D
      Returns:
      the boundary of this surface; null if a boundary cannot be computed
      See Also:
    • isClosedManifold

      public boolean isClosedManifold()
      Description copied from interface: Shape3D
      Determine if this Shape3D is a closed two-dimensional manifold.
      Specified by:
      isClosedManifold in interface Shape3D
      Returns:
      true if the surface is a closed two-dimensional manifold; false otherwise
    • triangles

      public CollectionScanner<Model3D.Triangle> triangles()
      Get a scanner that can iterate over the planar triangles provided by this model.
      Returns:
      a CollectionScanner that can be used to iterate over the triangles associated with this model
    • trianglesAndPatches

      public CollectionScanner<Model3D.Triangle> trianglesAndPatches()
      Get a collection scanner that can iterate over planar triangles, Bézier triangles, and Bézier patches.
      Returns:
      an iterator
    • setULPFactor

      public void setULPFactor(double ulpFactor)
      Set the ULP factor for this model. When the argument provided to this method is nonzero, Model3D will attempt to coallesce nearby values to prevent inconsistencies due to floating point errors. A value x is considered close to a previously provided value if within one a multiple, equal to the argument of this method, of the single-precision ULP (Unit of Least Precision) value for x. When within this range, the value x will be replaced with a previously provided value.

      Unless the value is 0, it must be positive and no less than 2.0. The default value is 0.0.

      Parameters:
      ulpFactor - a multiple used to scale the floating-point ULP value; 0.0 to disable its use
      Throws:
      IllegalArgumentException - the argument is out of range
      IllegalStateException - this method was called after objects were added to this model
    • tessellate

      public Iterator<Model3D.Triangle> tessellate()
      Get an iterator that will return a sequence of triangles after tessellation using the preset tessellation level
      Returns:
      an iterator
      See Also:
    • tessellate

      public Iterator<Model3D.Triangle> tessellate(int level)
      Get an iterator that will return a sequence of triangles after tessellation.
      Parameters:
      level - the tessellation level
      Returns:
      an iterator
      Throws:
      IllegalArgumentException - the tessellation level was negative
    • size

      public int size()
      Return the number of triangles and cubic patches in a model. The value returned is the value before any tessellation.
      Returns:
      the number of triangles and cubic patches in this model.
    • append

      public final void append(SurfaceIterator si, Object tag) throws IllegalArgumentException
      Append the surface segments specified by a surface iterator.
      Parameters:
      si - the surface iterator
      tag - a tag to label the segments added by this method
      Throws:
      IllegalArgumentException - the surface iterator returned segments from a non-oriented 3D shape
    • append

      public final void append(Shape3D surface) throws IllegalArgumentException
      Append the surface segments specified by another surface.
      Parameters:
      surface - the other surface
      Throws:
      IllegalArgumentException - the surface was not an oriented surface
    • append

      public final void append(Shape3D surface, Transform3D transform) throws IllegalArgumentException
      Append the surface segments specified by another surface after applying a transformation.
      Parameters:
      surface - the other surface
      transform - the transform to apply to a surface's control points
      Throws:
      IllegalArgumentException - the surface was not an oriented surface
    • addModel

      public void addModel(Model3DOps<?> m3d)
      Add a generalized model.

      This class implements an interface named Model3DOps that provides the operations needed to add components to a model and to implement the Shape3D interface. This method is provided so that other implementations of the Model3DOps interface can be used to create models that will be imported into the current model.

      Specified by:
      addModel in interface Model3DOps<Model3D.Triangle>
      Parameters:
      m3d - the model.
      Throws:
      IllegalArgumentException - if a model is being added to itself
    • addModel

      public void addModel(Model3DOps<?> m3d, Object tag)
      Add a generalized model, including a tag.

      This class implements an interface named Model3DOps that provides the operations needed to add components to a model and to implement the Shape3D interface. This method is provided so that other implementations of the Model3DOps interface can be used to create models that will be imported into the current model.

      Specified by:
      addModel in interface Model3DOps<Model3D.Triangle>
      Parameters:
      m3d - the model
      tag - a tag to name this call to addModel
      Throws:
      IllegalArgumentException - if a model is being added to itself
    • addModel

      public void addModel(Model3D m3d)
      Add the objects in another Model3D to this model.
      Parameters:
      m3d - a model containing objects to add
    • addModel

      public void addModel(Model3D m3d, Object tag)
      Add the objects in another Model3D to this model and tag them.
      Parameters:
      m3d - a model containing objects to add
      tag - a tag to label the objects added
      Throws:
      IllegalArgumentException - if a model is being added to itself
    • addModel

      public void addModel(Model3D m3d, boolean tessellate)
      Add a possibly tessellated 3D model to this model. When the second argument is true, only triangles are added and these are computed using argument model's tessellation level. When the second argument is false, this method is equivalent to addModel(Model3D).

      Models with multiple components may require different levels of tessellation for each. For example, some 3D printing services charge a fee per part, but count interlocking parts as a single part. Components used to tie parts together to reduce the per-part fee will be discarded after printing, and do not need as high a level of tessellation as other parts.

      Note: if an isolated component consists of planar triangles, including ones created by using classes such as SteppedGrid, the method tessellate() will not subdivide those triangles regardless of the tessellation level.

      Parameters:
      m3d - the model to add
      tessellate - true of the model being added should be tessellated; false otherwise
    • pushTransform

      public void pushTransform(Transform3D transform)
      Add a transform that will be applied to a triangle when it is added to the model. The transform is applied to the triangle's vertices. The edges will still be straight. For cubic patches, triangles, and vertices, the transform is applied to each control point.

      This method can be used to create a variety of objects from existing models by distorting them. The transforms are applied in the order in which they were added. This is the opposite of the order used by pushParms(). The transforms are general transforms.

      Transforms set using pushTransform(Transform3D) are applied before the transforms set using setObjectTranslation, setObjectTranslation, setObjectRotation(double,double,double) or pushParms().

      Parameters:
      transform - the transform to apply.
      Throws:
      IllegalArgumentException - the argument was null
      See Also:
    • popTransform

      public void popTransform()
      Remove the last transform that was added.
      Throws:
      IllegalStateException - the transform stack was empty
    • addTriangle

      public Model3D.Triangle addTriangle(Model3DOps.Triangle triangle)
      Add a triangle to the model. The triangle that is stored may differ from the triangle passed as this method's argument: while the type may be different, some classes that implement Model3DOps can apply transformations and will need to create a different triangle as a result.

      Transforms that cause a modified triangle to be stored can be configured using pushTransform(Transform3D) and popTransform().

      Specified by:
      addTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      triangle - the triangle to add
      Returns:
      the triangle stored by this model
      See Also:
    • addTriangle

      public Model3D.Triangle addTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3) throws IllegalArgumentException
      Description copied from interface: Model3DOps
      Add a triangle to the model, specifying the triangle by its vertices. The orientation of the triangle is determined by the right-hand rule when going from vertex 1 to vertex 2 to vertex 3.
      Specified by:
      addTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      x1 - the x coordinate of vertex 1
      y1 - the y coordinate of vertex 1
      z1 - the z coordinate of vertex 1
      x2 - the x coordinate of vertex 2
      y2 - the y coordinate of vertex 2
      z2 - the z coordinate of vertex 2
      x3 - the x coordinate of vertex 3
      y3 - the y coordinate of vertex 3
      z3 - the z coordinate of vertex 3
      Returns:
      the triangle stored by this model
      Throws:
      IllegalArgumentException - one of the first 9 arguments had the value Double.NaN
    • addFlippedTriangle

      public Model3D.Triangle addFlippedTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3) throws IllegalArgumentException
      Description copied from interface: Model3DOps
      Add a flipped triangle to the model, specifying the triangle by its vertices. The orientation of the triangle is the opposite to what the right-hand rule when going from vertex 1 to vertex 2 to vertex 3 would suggest.
      Specified by:
      addFlippedTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      x1 - the x coordinate of vertex 1
      y1 - the y coordinate of vertex 1
      z1 - the z coordinate of vertex 1
      x2 - the x coordinate of vertex 2
      y2 - the y coordinate of vertex 2
      z2 - the z coordinate of vertex 2
      x3 - the x coordinate of vertex 3
      y3 - the y coordinate of vertex 3
      z3 - the z coordinate of vertex 3
      Returns:
      the triangle stored by this model
      Throws:
      IllegalArgumentException - one of the first 9 arguments had the value Double.NaN
    • addTriangle

      public Model3D.Triangle addTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color) throws IllegalArgumentException
      Description copied from interface: Model3DOps
      Add a triangle to the model, specifying the triangle by its vertices and its color. The orientation of the triangle is determined by the right-hand rule when going from vertex 1 to vertex 2 to vertex 3.
      Specified by:
      addTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      x1 - the x coordinate of vertex 1
      y1 - the y coordinate of vertex 1
      z1 - the z coordinate of vertex 1
      x2 - the x coordinate of vertex 2
      y2 - the y coordinate of vertex 2
      z2 - the z coordinate of vertex 2
      x3 - the x coordinate of vertex 3
      y3 - the y coordinate of vertex 3
      z3 - the z coordinate of vertex 3
      color - the color of the triangle; null if none is specified
      Returns:
      the triangle stored by this model
      Throws:
      IllegalArgumentException - one of the first 9 arguments had the value Double.NaN
    • addFlippedTriangle

      public Model3D.Triangle addFlippedTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color) throws IllegalArgumentException
      Description copied from interface: Model3DOps
      Add a flipped triangle to the model, specifying the triangle by its vertices and color. The orientation of the triangle is the opposite to what the right-hand rule when going from vertex 1 to vertex 2 to vertex 3 would suggest.
      Specified by:
      addFlippedTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      x1 - the x coordinate of vertex 1
      y1 - the y coordinate of vertex 1
      z1 - the z coordinate of vertex 1
      x2 - the x coordinate of vertex 2
      y2 - the y coordinate of vertex 2
      z2 - the z coordinate of vertex 2
      x3 - the x coordinate of vertex 3
      y3 - the y coordinate of vertex 3
      z3 - the z coordinate of vertex 3
      color - the color of the triangle; null if none is specified
      Returns:
      the triangle stored by this model
      Throws:
      IllegalArgumentException - one of the first 9 arguments had the value Double.NaN
    • addTriangle

      public Model3D.Triangle addTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color, Object tag) throws IllegalArgumentException
      Description copied from interface: Model3DOps
      Add a triangle to the model, specifying the triangle by its vertices and its color, also specifying a tag. The orientation of the triangle is determined by the right-hand rule when going from vertex 1 to vertex 2 to vertex 3.
      Specified by:
      addTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      x1 - the x coordinate of vertex 1
      y1 - the y coordinate of vertex 1
      z1 - the z coordinate of vertex 1
      x2 - the x coordinate of vertex 2
      y2 - the y coordinate of vertex 2
      z2 - the z coordinate of vertex 2
      x3 - the x coordinate of vertex 3
      y3 - the y coordinate of vertex 3
      z3 - the z coordinate of vertex 3
      color - the color of the triangle; null if none is specified
      tag - the tag; null if there is none
      Returns:
      the triangle stored by this model
      Throws:
      IllegalArgumentException - a tag was a triangle or one of the first 9 arguments had the value Double.NaN
    • addFlippedTriangle

      public Model3D.Triangle addFlippedTriangle(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, Color color, Object tag) throws IllegalArgumentException
      Description copied from interface: Model3DOps
      Add a flipped triangle to the model, specifying the triangle by its vertices and color, also specifying a tag. The orientation of the triangle is the opposite to what the right-hand rule when going from vertex 1 to vertex 2 to vertex 3 would suggest.
      Specified by:
      addFlippedTriangle in interface Model3DOps<Model3D.Triangle>
      Parameters:
      x1 - the x coordinate of vertex 1
      y1 - the y coordinate of vertex 1
      z1 - the z coordinate of vertex 1
      x2 - the x coordinate of vertex 2
      y2 - the y coordinate of vertex 2
      z2 - the z coordinate of vertex 2
      x3 - the x coordinate of vertex 3
      y3 - the y coordinate of vertex 3
      z3 - the z coordinate of vertex 3
      color - the color of the triangle; null if none is specified
      tag - the tag; null if there is none
      Returns:
      the triangle stored by this model
      Throws:
      IllegalArgumentException - a tag was a triangle or one of the first 9 arguments had the value Double.NaN
    • removeTriangle

      public void removeTriangle(Object tag)
      Remove a triangle. Only triangles with tags can be removed.
      Parameters:
      tag - the triangle's tag.
    • addLineSegment

      public Model3D.LineSegment addLineSegment(Model3D.LineSegment segment)
      Add a line segment.
      Parameters:
      segment - the line segment to add.
      Returns:
      the line segment that was added
    • addLineSegment

      public Model3D.LineSegment addLineSegment(double x1, double y1, double z1, double x2, double y2, double z2)
      Add a line segment given the coordinates of its end points. The line segment is a straight line going from point p1 to another point p2.
      Parameters:
      x1 - the x coordinate of point 1
      y1 - the y coordinate of point 1
      z1 - the z coordinate of point 1
      x2 - the x coordinate of point 2
      y2 - the y coordinate of point 2
      z2 - the z coordinate of point 2
      Returns:
      the line segment that was added
    • addLineSegment

      public Model3D.LineSegment addLineSegment(double x1, double y1, double z1, double x2, double y2, double z2, Color color)
      Add a line segment given the coordinates of its end points and color. The line segment is a straight line going from point p1 to another point p2.
      Parameters:
      x1 - the x coordinate of point 1
      y1 - the y coordinate of point 1
      z1 - the z coordinate of point 1
      x2 - the x coordinate of point 2
      y2 - the y coordinate of point 2
      z2 - the z coordinate of point 2
      color - the line segment's color; null if no color is specified
      Returns:
      the line segment that was added
    • addLineSegment

      public Model3D.LineSegment addLineSegment(double x1, double y1, double z1, double x2, double y2, double z2, Color color, Object tag)
      Add a line segment given the coordinates of its end points, its color, and a tag. The line segment is a straight line going from point p1 to another point p2.
      Parameters:
      x1 - the x coordinate of point 1
      y1 - the y coordinate of point 1
      z1 - the z coordinate of point 1
      x2 - the x coordinate of point 2
      y2 - the y coordinate of point 2
      z2 - the z coordinate of point 2
      color - the line segment's color; null if no color is specified
      tag - a tag for the line segment; null if none is specified
      Returns:
      the line segment that was added
    • removeLineSegment

      public void removeLineSegment(Object tag)
      Remove a line segment.
      Parameters:
      tag - a tag naming the line segment
    • setImageParameters

      public Model3D.ImageParams setImageParameters(Model3D.ImageData idata)
      Set image parameters. The image data (idata) will be modified so that all the objects are within the border of the image.
      Parameters:
      idata - image data to read and modify
      Returns:
      the image parameters
    • setImageParameters

      public Model3D.ImageParams setImageParameters(Model3D.ImageData idata, double border)
      Set image parameters given a border. The image data (id) will be modified based on the other arguments so that all objects fit within the image and its border.
      Parameters:
      idata - image data to read and modify
      border - the minimum distance in user space from the edges of an image to the object(s) being displayed; -1 for a default
      Returns:
      the image parameters
    • setImageParameters

      public Model3D.ImageParams setImageParameters(Model3D.ImageData idata, double border, double magnification)
      Set image parameters given a border and magnification. The image data (id) will be modified based on the other arguments. The magnification field provides a factor by which an object is scaled up, so that a value of 2.0 doubles the size of the objects in an image. The fractional positions are 0.
      Parameters:
      idata - image data to read and modify
      border - the minimum distance in user space from the edges of an image to the object(s) being displayed; -1 for a default
      magnification - The magnification of the image.
      Returns:
      the image parameters
    • setImageParameters

      public Model3D.ImageParams setImageParameters(Model3D.ImageData idata, double magnification, double xfract, double yfract)
      Set image parameters given a magnification and fractional positions. The image data (id) will be modified based on the other arguments. The magnification field provides a factor by which an object is scaled up, so that a value of 2.0 doubles the size of the objects in an image. If xfract is 0.0, the minimum value of x for any object will appear at the left border. If xfract is 1.0, the maximum value of x for any object will appear at the right border. If yfract is 0, the minimum value of y for any object will appear at the bottom border. If yfract is 1.0, the maximum value of y for any object will appear at the top border. A default border will be used.
      Parameters:
      idata - image data to read and modify
      magnification - The magnification of the image.
      xfract - the fraction of the image width, excluding the borders, by which an image was shifted along the x axis, with values in the range [0.0, 1.0]
      yfract - the fraction of the image width, excluding the borders, by which an image was shifted along the y axis, with values in the range [0.0, 1.0]
      Returns:
      the image parameters
    • setImageParameters

      public Model3D.ImageParams setImageParameters(Model3D.ImageData id, double border, double magnification, double xfract, double yfract)
      Set image parameters given a border, magnification, and fractional positions. The image data (id) will be modified based on the other arguments. The magnification field provides a factor by which an object is scaled up, so that a value of 2.0 doubles the size of the objects in an image. If xfract is 0.0, the minimum value of x for any object will appear at the left border. If xfract is 1.0, the maximum value of x for any object will appear at the right border. If yfract is 0, the minimum value of y for any object will appear at the bottom border. If yfract is 1.0, the maximum value of y for any object will appear at the top border.
      Parameters:
      id - image data to read and modify
      border - the minimum distance in user space from the edges of an image to the object(s) being displayed; -1 for a default
      magnification - The magnification of the image.
      xfract - the fraction of the image width, excluding the borders, by which an image was shifted along the x axis, with values in the range [0.0, 1.0]
      yfract - the fraction of the image width, excluding the borders, by which an image was shifted along the y axis, with values in the range [0.0, 1.0]
      Returns:
      the image parameters
    • setImageParameters

      public Model3D.ImageParams setImageParameters(Model3D.ImageData id, double border, double magnification, double xfract, double yfract, boolean changeScale)
      Set image parameters given a border, magnification, fractional positions, and a scaling option The image data (id) will be modified based on the other arguments. The magnification field provides a factor by which an object is scaled up, so that a value of 2.0 doubles the size of the objects in an image. If xfract is 0.0, the minimum value of x for any object will appear at the left border. If xfract is 1.0, the maximum value of x for any object will appear at the right border. If yfract is 0, the minimum value of y for any object will appear at the bottom border. If yfract is 1.0, the maximum value of y for any object will appear at the top border.
      Parameters:
      id - image data to read and modify
      border - the minimum distance in user space from the edges of an image to the object(s) being displayed; -1 for a default
      magnification - The magnification of the image.
      xfract - the fraction of the image width, excluding the borders, by which an image was shifted along the x axis, with values in the range [0.0, 1.0]
      yfract - the fraction of the image width, excluding the borders, by which an image was shifted along the y axis, with values in the range [0.0, 1.0]
      changeScale - true if the scale should be changed; false if not
      Returns:
      the image parameters
    • render

      public void render(Model3D.Image image)
      Render a model. The render list, a list of triangles sorted by stacking order, will be cleared afterwards.
      Parameters:
      image - the image which will contain the rendered model
    • render

      public void render(Model3D.Image image, boolean keep)
      Render a model, optionally preserving the render list so that additional objects can be added.
      Parameters:
      image - the image which will contain the rendered model
      keep - true if the render list should be preserved; false if not.
    • render

      public void render(Model3D.Image image, boolean keep, double tx, double ty)
      Render a model, optionally preserving the render list so that additional objects can be added and translating the coordinate system for the model.
      Parameters:
      image - the image which will contain the rendered model
      keep - true if the render list should be preserved; false if not.
      tx - the x coordinate of the new origin's location
      ty - the y coordinate of the new origin's location
    • render

      public void render(Model3D.ImageData id, Graphics2D g2d)
      Render a model given a graphics context.
      Parameters:
      id - the image data for rendered model
      g2d - the graphics context to use
    • render

      public void render(Model3D.ImageData id, Graphics2D g2d, boolean keep)
      Render a model given a graphics context and a render-list preservation flag.
      Parameters:
      id - the image data for rendered model
      g2d - the graphics context to use
      keep - true if the render list should be preserved; false if not.
    • render

      public void render(Model3D.ImageData id, Graphics2D g2d, boolean keep, double tx, double ty)
      Render a model given a graphics context and translations.
      Parameters:
      id - the image data for rendered model
      g2d - the graphics context to use
      keep - true if the render list should be preserved; false if not.
      tx - the x coordinate of the new origin's location
      ty - the y coordinate of the new origin's location
    • verifyClosed2DManifold

      public List<Model3D.Edge> verifyClosed2DManifold()
      Test that the model consists of a closed 2D manifold. The orientation of a triangle is determined by using a "right hand rule" when traversing vertices. For a manifold to be two dimensional, each edge must be traversed no more than twice and to be closed, each edge must be traversed exactly twice, once in each direction. Thus, each edge must be shared by exactly two triangles. A less stringent test is useful in 3D printing: two cubes that touch on a edge but share a common base are printable, but the surface is not a manifold (although it would be if the cubes were offset from each other by a tiny amount). The constructor Model3D(boolean) allows one to specify a "strict" mode, where true requires that the surface is manifold and false allows multiple surfaces to touch at an edge.

      In addition, the rules for a valid STL file preclude partially overlapping edges.

      Returns:
      a list of edges for which the test failed; null if it succeeded
    • verifyEmbedded2DManifold

      public List<Model3D.Triangle> verifyEmbedded2DManifold()
      Test that the model's 2D manifold is embedded in a Euclidean 3 dimensional space. The model is assumed to consist only of triangles: cubic patches, cubic vertices, and cubic triangles are ignored. To test these, first create a tessellated model. Given that the manifold is represented by a set of triangles, the requirement is that triangles do not intersect.
      Returns:
      a list of triangles, each pair of which intersect each other.
    • verifyEmbedded2DManifold

      public List<Model3D.Triangle> verifyEmbedded2DManifold(double limit)
      Test that the model's 2D manifold is embedded in a Euclidean 3 dimensional space, setting a test limit. The model is assumed to consist only of triangles: cubic patches, cubic vertices, and cubic triangles are ignored. To test these, first create a tessellated model. Given that the manifold is represented by a set of triangles, the requirement is that triangles do not intersect.

      The limit (the default is Math.ulp(1F)) is a bound on how far from zero values may be and still be considered to be zero. The limit is intended to account for round-off errors. The method verifyEmbedded2DManifold() uses the default limit.

      Parameters:
      limit - the limit (a non-negative number)
      Returns:
      a list of triangles, each pair of which intersect each other.
    • numberOfComponents

      public int numberOfComponents() throws ManifoldException
      Get the number of manifold components for a model.
      Specified by:
      numberOfComponents in interface Shape3D
      Returns:
      the number of manifold components for the current model
      Throws:
      ManifoldException - the model is ill-formed and its components (the components of a manifold) cannot be computed.
    • getComponent

      public Model3D getComponent(int index) throws ManifoldException
      Get a manifold component. The components are referenced by an index, specified as an integer in the range [0,n), where n is the number of manifold components. If n is zero, no index is valid.
      Specified by:
      getComponent in interface Shape3D
      Parameters:
      index - the component's index
      Returns:
      a model containing the specified component
      Throws:
      ManifoldException - the model is ill-formed and its components (the components of a manifold) cannot be computed.
      See Also:
    • notHollow

      public boolean notHollow() throws ManifoldException
      Determine if some manifold component represents a vacant space.
      Returns:
      true if the model has no inward-facing surfaces; false if it does
      Throws:
      ManifoldException - the model is ill-formed and its components (the components of a manifold) cannot be computed.
    • notHollow

      public boolean notHollow(Appendable out) throws ManifoldException, IOException
      Determine if some manifold component represents a vacant space and optionally store a record of the results.
      Parameters:
      out - an Appendable for recording details; null for no output
      Returns:
      true if the model has no inward-facing surfaces; false if it does
      Throws:
      ManifoldException - the model is ill-formed and its components (the components of a manifold) cannot be computed.
      IOException - an error occurred during writing
    • isComponentHollow

      public boolean isComponentHollow(int index) throws ManifoldException
      Determine if a component of a 3D model is hollow. The precondition for using this method is that the model is a closed 2D manifold embedded in a Euclidean three-dimensional space.
      Parameters:
      index - the index of a component.
      Returns:
      true if the component is hollow (i.e., the normal vectors of its triangles point inwards, not outwards); false otherwise
      Throws:
      ManifoldException - the model is ill-formed and its components (the components of a manifold) cannot be computed.
    • verifyNesting

      public boolean verifyNesting()
      Test that the model compoents are properly nested.
      Returns:
      true if the components are properly nested; false otherwise
    • verifyNesting

      public boolean verifyNesting(Appendable out) throws ManifoldException
      Test that the model compoents are properly nested, and record errors.
      Parameters:
      out - the output appendable
      Returns:
      true if the components are properly nested; false otherwise
      Throws:
      ManifoldException - the model is ill-formed and its components (the components of a manifold) cannot be computed.
    • printable

      public boolean printable()
      Test if a model is printable on a 3D printer.. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed. This method assumes that hollow objects are not allowed for 3D printing.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Returns:
      true if the model can be printed; false otherwise
    • printable

      public boolean printable(Appendable out) throws IOException
      Test if a model is printable on a 3D printer, given an Appendable for error-message output. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed. This method assumes that hollow objects are not allowed for 3D printing.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Parameters:
      out - the output on which to print error messages; null if none is to be used
      Returns:
      true if the model cannot be printed; false otherwise
      Throws:
      IOException - an IO exception occurred when printing error messages
    • printable

      public boolean printable(boolean hollow)
      Test if a model is printable on a 3D printer, specifying whether hollow objects are allowed. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Parameters:
      hollow - true if the printer allows hollow objects; false if not.
      Returns:
      true if the model cannot be printed; false otherwise
    • printable

      public boolean printable(boolean hollow, Appendable out) throws IOException
      Test if a model is printable on a 3D printer, given an Appendable for error-message output and specifying whether hollow objects are allowed. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Parameters:
      hollow - true if the printer allows hollow objects; false if not.
      out - the output on which to print error messages; null if none is to be used
      Returns:
      true if the model cannot be printed; false otherwise
      Throws:
      IOException - an IO exception occurred when printing error messages
    • notPrintable

      public boolean notPrintable()
      Test if a model is not printable on a 3D printer.. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed. This method assumes that hollow objects are not allowed for 3D printing.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Returns:
      true if the model cannot be printed; false otherwise
    • notPrintable

      public boolean notPrintable(Appendable out) throws IOException
      Test if a model is not printable on a 3D printer, given an Appendable for error-message output. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed. This method assumes that hollow objects are not allowed for 3D printing.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Parameters:
      out - the output on which to print error messages; null if none is to be used
      Returns:
      true if the model cannot be printed; false otherwise
      Throws:
      IOException - an IO exception occurred when printing error messages
    • notPrintable

      public boolean notPrintable(boolean hollow)
      Test if a model is not printable on a 3D printer, specifying whether hollow objects are allowed. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities.

      Parameters:
      hollow - true if the printer allows hollow objects; false if not.
      Returns:
      true if the model cannot be printed; false otherwise
    • notPrintable

      public boolean notPrintable(boolean hollow, Appendable out) throws IOException
      Test if a model is not printable on a 3D printer, given an Appendable for error-message output and specifying whether hollow objects are allowed. 3D printing technologies such as laser sintering do not allow one to print hollow objects because material would be trapped inside the object being printed.

      Note: this test does not include physical constraints on dimensions. Rather it verifies that the object being printed has a surface that is a closed manifold, the it does not intersect itself, and that components are ordered correctly so that what should be the inside of an object is not the outside of that object. Specific printers will usually have constraints on a model such as minimal thicknesses for "walls" and "wires", and minimum sizes for holes for letting material be removed from cavities. The test for self intersection apply only to a model's triangles. If a model contains a cubic patch, cubic vertices, or cubic triangles, a tessellated model should be created first.

      Parameters:
      hollow - true if the printer allows hollow objects; false if not.
      out - the output on which to print error messages; null if none is to be used
      Returns:
      true if the model cannot be printed; false otherwise
      Throws:
      IOException - an IO exception occurred when printing error messages
    • area

      public double area()
      Compute the surface area of a 3D model The model must be a closed manifold embedded in a two-dimensional space. The units are those used by graph-coordinate space.

      Implementation note: the result of this computation will be cached so that subsequent calls to this method will simply use the cached value (which is cleared if a triangle is added to the model).

      Returns:
      the surface area
    • volume

      public double volume()
      Compute the volume of a 3D model The model must be a closed manifold embedded in a two-dimensional space. The units are those used by graph-coordinate space. The normal vector is assumed to be in the direction implied by the right-hand rule as each triangle's vertices are traversed in the order defined. If the normal vectors for the triangles in a manifold point outwards, the volume returned will be positive; otherwise it may be negative. One can use inward pointing normal vectors to represent a cavity, but such models typically cannot be 3D printed as material will be trapped inside. A cube with x, y, and z varying from 0.0 to 1.0 will have a volume of 1.0.

      The algorithm used to compute the volume has a complexity linear in the number of triangles: the algorithm uses Gauss' theorem to turn the volume computation into a surface integral, and for each triangle, the integral can be evaluated in closed form.

      Implementation note: the result of this computation will be cached so that subsequent calls to this method will simply use the cached value (which is cleared if a triangle is added to the model).

      Returns:
      the volume
    • setSTLBase

      public void setSTLBase(boolean value)
      Set whether or not an STL base is used. An STL base provides a translation that sets the minimum x, y, and z coordinates to some value, always a positive one (STL files generally contain only positive vertex positions). The default is true. If set to false the STL-base processing is ignored, and the coordinates provided by the model (some of these coordinates may be negative or zero) are used instead.
      Parameters:
      value - true if an STL base is used; false otherwise
    • setSTLBase

      public void setSTLBase(double offset)
      Set the value of STL Base. The STL Base parameters will be set so that the minimum values of x, y and z for objects in a model are given by offset. The default is 1.0.
      Parameters:
      offset - an offset determining the STL base.
    • setSTLBase

      public void setSTLBase()
      Set the value of STL Base to a default. Equivalent to setSTLBase(1.0).
    • setUnitScaleX3D

      public void setUnitScaleX3D(double value)
      Set the unit scale factor for X3D files. The default is 0.001 so that a length of 1.0 is 1 mm.
      Parameters:
      value - the length of a unit length in meters
    • getUnitScaleX3D

      public double getUnitScaleX3D()
      Get the unit scale factor for X3D files. The value is the length in meters of a unit-length in the model.
      Returns:
      the scale factor
    • writeX3D

      public void writeX3D(String title, String description, String creator, String fname) throws IOException
      Create an X3D file from the model, given a file name. The first three parameters are strings used in meta data. The file created will use the X3D binary format if the JRE supports the fast infoset format; otherwise the format will default to the XML format. To control the format explicitly, use writeX3D(String,String,String,OutputStream,boolean).

      The XML format before a infoset is created does not have a DOCTYPE declaration: tests indicated that the corresponding DTD was not being processed appropriately. The X3D file will specify an "Interchange" profile. If the file-name extension is "x3dz" or "X3DZ", the file will be compressed.

      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      fname - the name of the file
      Throws:
      IOException - an IO error occurred
    • writeX3D

      public void writeX3D(String title, String description, String creator, boolean full, String fname) throws IOException
      Create an X3D file from the model, given a file name and specifying a profile. The first three parameters are strings used in meta data. use writeX3D(String,String,String,OutputStream,boolean). If the file-name extension is "x3dz" or "X3DZ", the file will be compressed.

      The XML format before a infoset is created does not have a DOCTYPE declaration: tests indicated that the corresponding DTD was not being processed appropriately.

      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      full - true if the Full X3D profile should be used; false for the Interchange profile
      fname - the name of the file
      Throws:
      IOException - an IO error occurred
    • writeSTL

      public void writeSTL(String id, String fname) throws IOException
      Create an STL file from the model, given a file name. The file created will use the X3D binary format if the JRE supports the fast infoset format; otherwise the format will default to the XML format. To control the format explicitly, use writeX3D(String,String,String,OutputStream,boolean).
      Parameters:
      id - the STL file's ID string (limited to 80 7-bit ASCII characters)
      fname - the name of the file
      Throws:
      IOException - an error occurred when opening or writing the file
    • writeSTL

      public void writeSTL(String id, File f) throws IOException
      Create an STL file from the model, given a file. The file created will use the X3D binary format if the JRE supports the fast infoset format; otherwise the format will default to the XML format. To control the format explicitly, use writeX3D(String,String,String,OutputStream,boolean).
      Parameters:
      id - the STL file's ID string (limited to 80 7-bit ASCII characters)
      f - the output file
      Throws:
      IOException - an error occurred when opening or writing the file
    • writeX3D

      public void writeX3D(String title, String description, String creator, File f) throws IOException
      Create an X3D file from the model, given a File. The first three parameters are strings used in meta data. The X3D file will specify a "Interchange" profile. If the file-name extension is "x3dz" or "X3DZ", the file will be compressed.
      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      f - the file
      Throws:
      IOException - an IO error occurred
    • writeX3D

      public void writeX3D(String title, String description, String creator, boolean full, File f) throws IOException
      Create an X3D file from the model, given a File and specifying a profile. The first three parameters are strings used in meta data. If the file-name extension is "x3dz" or "X3DZ", the file will be compressed.
      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      full - true if the Full X3D profile should be used; false for the Interchange profile
      creator - the file's author; null for a default
      f - the file
      Throws:
      IOException - an IO error occurred
    • writeSTL

      public void writeSTL(String id, OutputStream out) throws IOException
      Create an STL file from the model, given an output stream.
      Parameters:
      id - the STL file's ID string (limited to 80 7-bit ASCII characters)
      out - the output stream
      Throws:
      IOException - an error occurred when writing to the stream
    • writeX3D

      public void writeX3D(String title, String description, String creator, OutputStream os) throws IOException
      Create an X3D file from the model, given an output stream. The first three parameters are strings used in meta data. The X3D file will specify an "Interchange" profile. The file will not be compressed.
      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      os - the output stream
      Throws:
      IOException - an IO error occurred
    • writeX3D

      public void writeX3D(String title, String description, String creator, boolean full, OutputStream os) throws IOException
      Create an X3D file from the model, specifying a profile and given an output stream. The first three parameters are strings used in meta data. The file will not be compressed.
      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      full - true if the Full X3D profile should be used; false for the Interchange profile
      os - the output stream
      Throws:
      IOException - an IO error occurred
    • writeX3D

      public void writeX3D(String title, String description, String creator, OutputStream os, boolean compress) throws IOException
      Create an X3D file in either binary or XML format from the model, given an output stream. The first three parameters are strings used in meta data. The binary format is a fast infoset encoding of the XML file. Currently it is not supported but may be in future releases. The X3D file will specify an "Interchange" profile.
      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      os - the output stream
      compress - true if the file should be compressed; false otherwise
      Throws:
      IOException - an IO error occurred
      UnsupportedOperationException - binary encoding is not supported
    • writeX3D

      public void writeX3D(String title, String description, String creator, boolean full, OutputStream os, boolean compress) throws IOException
      Create an X3D file in either binary or XML format from the model, given a profile specification and an output stream. The first three parameters are strings used in meta data.

      If compressed, the output stream will be automatically closed

      Parameters:
      title - the title of the file; null for a default
      description - a description of the file; null for a default
      creator - the file's author; null for a default
      full - true if the Full X3D profile should be used; false for the Interchange profile
      os - the output stream
      compress - true if the file should be compressed; false for XML alone
      Throws:
      IOException - an IO error occurred
      UnsupportedOperationException - binary encoding is not supported
    • writeSTL

      public void writeSTL(String id, WritableByteChannel c) throws IOException
      Create an STL file from the model, given a writable byte channel.
      Parameters:
      id - the STL file's ID string (limited to 80 7-bit ASCII characters)
      c - the output channel
      Throws:
      IOException - an error occurred when writing to the channel
    • createImageSequence

      public void createImageSequence(OutputStream os, String imageType, int nphi, int ntheta) throws IOException
      Create a sequence of images. The images will be created in the format supported by ImageSequenceWriter. When the number of steps is 0, only a single image will appear in the sequence. When θ is 0 or 180 degrees, $phi; will be set to 0. if nphi is 0, φ will also be set to 0. Otherwise for each value of θ φ will range from 0 to 360 in steps of 360/nphi.

      The images show the edges of triangles in green, and shows the interior side of a triangle in red. The background is a dark blue and the model is various shades of gray depending on a triangle's orientation. This is intended for visual model checking.

      Parameters:
      os - the output stream
      imageType - the image type
      nphi - the number of steps for the Eulerian angle φ
      ntheta - the number of steps for the Eulerian angle $theta;
      Throws:
      IOException - if an IO error occurred
    • createImageSequence

      public void createImageSequence(OutputStream os, String imageType, int nphi, int ntheta, double delta, double colorFactor) throws IOException
      Create a sequence of images, specifying a color factor and the maximum triangle size for rendering. The images will be created in the format supported by ImageSequenceWriter. When the number of steps is 0, only a single image will appear in the sequence. When θ is 0 or 180 degrees, $phi; will be set to 0. if nphi is 0, φ will also be set to 0. Otherwise for each value of θ φ will range from 0 to 360 in steps of 360/nphi.

      The parameters delta and colorFactor are used to fine-tune the images. A non-zero value of delta will result in triangles above a critical size being partitioned into smaller triangles for rendering in order to reduce Z-ordering problems. A non-zero color factor will cause triangles with lower Z values (after all transformations and coordinate-system rotations) to appear darker. This is useful when a model has multiple parallel surfaces with different Z values. and the user otherwise cannot distinguish them.

      The images show the edges of triangles in green, and shows the interior side of a triangle in red. The background is a dark blue and the model is various shades of gray depending on a triangle's orientation. This is intended for visual model checking.

      Parameters:
      os - the output stream
      imageType - the image type
      nphi - the number of steps for the Eulerian angle φ
      ntheta - the number of steps for the Eulerian angle $theta;
      delta - the maximum triangle size for rendering; 0.0 if this parameter should be ignored
      colorFactor - the color factor; 0.0 if this parameter should be ignored
      Throws:
      IOException - if an IO error occurred
      See Also:
    • createImageSequence

      public void createImageSequence(OutputStream os, String imageType, int nphi, int ntheta, double delta, double colorFactor, double normalFactor, boolean showEdges) throws IOException
      Create a sequence of images, specifying a color factor, normal factor and the maximum triangle size for rendering. The images will be created in the format supported by ImageSequenceWriter. When the number of steps is 0, only a single image will appear in the sequence. When θ is 0 or 180 degrees, $phi; will be set to 0. if nphi is 0, φ will also be set to 0. Otherwise for each value of θ φ will range from 0 to 360 in steps of 360/nphi.

      The parameters delta and colorFactor are used to fine-tune the images. A non-zero value of delta will result in triangles above a critical size being partitioned into smaller triangles for rendering in order to reduce Z-ordering problems. A non-zero color factor will cause triangles with lower Z values (after all transformations and coordinate-system rotations) to appear darker. This is useful when a model has multiple parallel surfaces with different Z values. and the user otherwise cannot distinguish them. The color factor is useful primarily for surfaces that are in the X-Y plane after coordinate transformations. If the the normal factor is set to a small positive value, the color factor will be effectively reduced when triangles whose normal vectors are not aligned with the Z axis are rendered. For a normal factor f, the color factor will be reduced by a factor of exp(-(1-nz)/f) where nz is the Z component of the normal vector.

      The images show the edges of triangles in green, and shows the interior side of a triangle in red. The background is a dark blue and the model is various shades of gray depending on a triangle's orientation. This is intended for visual model checking.

      Parameters:
      os - the output stream
      imageType - the image type
      nphi - the number of steps for the Eulerian angle φ
      ntheta - the number of steps for the Eulerian angle $theta;
      delta - the maximum triangle size for rendering; 0.0 if this parameter should be ignored
      colorFactor - the color factor; 0.0 if this parameter should be ignored
      normalFactor - the normal factor; 0.0 if there is none
      showEdges - true if edges of triangles and patches should be shown; false otherwise
      Throws:
      IOException - if an IO error occurred
      See Also:
    • createCrossSection

      public void createCrossSection(Graph graph, double xp, double yp, double zp, double[] normal)
      Generate a graph containing a cross section of this model, using the current tessellation level, where triangle edges pass through a plane that passes through the point (xp, yp, zp) and perpendicular to a normal vector.

      The orientation of the cross section is implementation dependent, but may be rotated by 90 degrees if that will result in a larger image. The triangles and edges that go through the plane will be drawn, projected onto the plane, and will be denoted by black lines. Any edges and triangles reported by the methods verifyClosed2DManifold() or verifyEmbedded2DManifold() will be denoted by red lines. After this method is called, the graph should be written or otherwise displayed. The graph will have its offsets and ranges set automatically. For example, in a test case that purposely generated an error and where notPrintable(Appendable) printed

      
       3D model's surface is not embedded in a three-dimensional space:
       Planar Triangle (-6.70000,2.30000,4.70000)-(-6.70000,6.70000,4.70000)-(-1.10000,1.90526,4.70000)
       Planar Triangle (-3.00000,3.00000,8.00000)-(3.00000,3.00000,4.00000)-(-3.00000,3.00000,4.00000)
      
       
      The code
      
       Graph graph = new Graph(700, 700);
       m3d.createCrossSection(graph, -3.0, 3.0, 4.7,
                              new double[] {0.0, 1.0, 0.0});
       graph.write("png", "fakelock.png");
       
      produced the following image (truncated and rotated for display purposes:

      3D model that looks like a lock

      thus providing a visual representation of the error.

      Parameters:
      graph - the graph
      xp - the X coordinate of the designated point on the plane
      yp - the Y coordinate of the designated point on the plane
      zp - the Z coordinate of the designated point on the plane
      normal - the normal vector for the plane
      Throws:
      IllegalArgumentException - if the graph or normal vector are null, if the graph's size is less than 200×200, of if the normal vector's norm is 0