IMPROVED RAPID PROTOTYPING METHOD

Abstract: A rapid prototype modeling system operates to first electronically decompose a discrete part represented by a stereolithography file into thick layers (36), which are then electronically sliced into cross-sectional slices (39) the thickness of a sheet (38) of construction material. The slices (39) are cut from sheets (38) of the construction material in a pattern which permits construction of the layers (36) by stacking the sheets (38). The layers (36) are then stacked appropriately to create a physical model of the discrete part.

Description: LMPRONED RAPID PROTOTYPING METHOD This application includes a computer program listing printout submitted in the form of an appendix. Technical Field: This invention relates to prototype modeling techniques. It is particularly directed to the construction of solid patterns derived from 3D CAD software-generated models. Background Art: Current rapid prototyping (RP) technology offers many advantages over more traditional prototyping techniques. For example, RP decreases the time required to produce an initial prototype. Currently available RP systems are generally flexible, and produce prototypes of superior accuracy. Unfortunately, they are also significantly more expensive to utilize than are traditional systems. Available techniques include stereolithography, laminated object manufacturing, fused deposition modeling, selective laser sintering, and ballistic particle manufacturing. These techniques in general operate on a common paradigm. They each decompose the part into a series of layers or cross sections. The part is then constructed by sequentially creating each layer and bonding it to the previous layer. This bonding usually occurs automatically as a part of the layer creation process. In the case of laminated object manufacturing, each layer is bonded prior to cutting the outline of the cross section. In any event, while several different parts may be built simultaneously on a common build platform, each layer of each discrete part must be created in sequential order. Traditional RP techniques incorporate various techniques for dealing with cantilever overhangs in the part during construction. A support structure is often created in stereolithography systems. In some systems, the excess material surrounding each cross section provides the necessary support. Parts with complex curves have little contact area with the support structure during the construction procedures of many existing RP techniques. For example, a sphere theoretically contacts the build platform at a single point. As the sphere is built up from this point contact, it can easily shift, destroying the registration of the layers. For a more generalized part, the operator must decide how to orient the part, attempting to minimize overhangs and maximize the support provided by the building platform. Construction of prototype parts by the application of RP technology usually requires the use of high-priced materials. Prohibitive costs have limited the proliferation of RP application to well-financed users, typically large companies with correspondingly substantial development budgets and RP service bureaus which demand large fees. Schools and typical smaller enteφrises often cannot justify the acquisition of RP systems. There is a need for an inexpensive system capable of making RP technology directly accessible to small businesses and students. DISCLOSURE OF INVENTION This invention provides an inexpensive rapid prototyping method which has particular application in the field of education as well as in various industrial fields. Practice of the method is facilitated with a novel system which typically interconnects commercially available hardware and software elements through customized hardware and software elements. The cost of the complete, fully operational system is significantly less than (typically, a small fraction of) the cost of current state-of-the-art RP systems. The accuracy of a prototype fabricated using a rudimentary system of this invention is adequate to demonstrate the form of a modeled object. More refined versions may in some instances produce prototypes adequate to meet fit or function requirements. In any case, the system of this invention is affordable for schools and small businesses. It allows the designer to make a physical inspection of a design at a very low cost, typically two or three orders of magnitude below the cost associated with prototyping by currently available RP technologies. The system of this invention creates a part from a series of cross sections as do conventional RP systems. A fundamental departure from prior systems resides in the layup iterations followed in bonding sequential layers together. This invention first creates all of the layers required, and then bonds the layers together, through a separate efficient procedure. This step, and the nature of the construction materials utilized, introduce significant additional flexibility to the final construction process. The invention avoids, for example, the limitation of existing RP systems whereby the layers must be created sequentially, one layer at a time. According to this invention, the part is first decomposed into thick slices, or layers. These layers can be positioned to eliminate unwanted overhangs prior to cutting the outline of the cross section. The system provides added flexibility by permitting the operator to mirror selected thick layers, building any such layer either from the bottom up or the top down. Thus, when making a sphere, the first thick section will be constructed from the top down, thereby providing a large area of contact between the build platform and the part. Subsequent layers are built from bottom to top because they have adequate contact area as so oriented. This mirroring of one of the layers is then corrected for during the subsequent assembly of the thick layers. The system operates to arrange thick layers of a single discrete part across a build platform. These layers may then be sliced to the thickness of the construction material. As a consequence, this invention can often create a part that requires many slices from few sheets of construction material. Assuming that a part is sufficiently small that a single sheet of construction material can accommodate 8 thick layers, 64 slices can be registered and bonded in 14 steps instead of 63. (The 8 sheets are registered and bonded, requiring 7 steps. Then the resulting 8 sections are registered and bonded, requiring 7 more steps.) A typical rudimentary system of this invention comprises a plotter, a personal computer, a simple registration stand (build table) and the software (ZWSLICE) disclosed in the microfiche appendix. ZWSLICE reads three dimensional ("3-D") solid models from commercially available drawing software, and electronically cuts them into paper-thin slices. The software-generated slices are converted to physical slices cut out on the plotter. The physical slices (typically of paper, plastic or other sheet material) are then stacked on the build table to construct a physical embodiment of the computer model. These embodiments may be treated as prototype parts. Alternatively, they may be used as patterns for constructing molds or shells from which to cast parts from metal or other rigid material. In other instances, they may be used as paper molds from which to produce plastic parts. The invention may be embodied as an inexpensive rapid prototyping device that creates physical models from 3D electronic computer-aided design ("CAD") models. It performs this function by generating a series of cross sections, slicing the part into many layers. Each cross section is cut from sheet construction material (usually paper) using a commercial sign making plotter. The cross sections are registered and laminated together forming the physical model. A primary advantage of the system of this invention is that the initial cost of the requisite hardware and software, as well as the cost of producing a typical part are 10 times to 20 times less expensive than existing rapid prototyping techniques. Assuming that the user already owns a computer and CAD software, the additional hardware and software required to complete the system may have a retail price on the order of a typical personal computer assembly. Individual sheets of construction material may include a construction layer and a backing layer fixed to the construction layer with adhesive material. Individual physical slices may then be cut from the construction layer, leaving the backing layer in tact. Individual pluralities of the physical slices may then be distributed in corresponding patterns among an ordered set of construction sheets. The plotting step may include locating index positions on the sheets of construction material, and the cutting step may include the placement of registration holes at the index positions through the construction sheets. The holes facilitate the precise registration of respective pluralities of the physical slices carried by individual construction sheets within the set when all of the construction sheets are stacked in the order of the set with registration pins inserted through the registration holes. The registration holes may also be located to facilitate the precise registration of constructed layers when they are stacked to recompose the object. Building speed is dependent upon a number of factors, including part dimensions, layer thickness, and operator skill. Typical building speeds range from about 0.2 to about 3.1 hours per vertical centimeter (one-half to about 8 hours per vertical inch). Because models can be constructed of readily available paper materials, construction costs are trivial compared to other RP systems. BRIEF DESCRIPTION OF DRAWINGS In the drawings, which illustrate what is currently regarded as the best mode for carrying out the invention: FIG. 1 is a flow diagram of a typical embodiment of the invention; FIG. 2 is a pictorial representation in two parts; FIG. 2a illustrating an STL representation of a solid model, and FIG. 2b illustrating that model sliced in the x, the y, and the z directions; FIG. 3 is a sketch of a plot file illustrating the layout of slices of the part of FIG. 2 and registration holes on one sheet of construction material; FIG. 4 is a pictorial view of a registration table of the invention; FIG. 5 is a view in elevation of the registration table of FIG. 4 illustrating a stacked arrangement of the slices from a plurality of sheets of the type illustrated by FIG. 3; FIG. 6 is a two-part view in cross section; FIG. 6a illustrating unsupported overhangs which may occur, and FIG. 6b iUustrating a solution to this problem through hierarchical model decomposition; FIG. 7 is a pictorial view of typical prototype parts which may be constructed by the system of the invention; FIG. 8 is a two-part drawing of which 8a illustrates the layup of a pattern useful for sand casting; and FIG. 8b illustrates the cope and the drag elements of a mold; FIG. 9 is a flow diagram illustrating an investment casting procedure utilizing prototypes constructed in accordance with the invention; FIG. 10 is a schematic illustration of a lost foam casting utilization of a foam model produced in accordance with the invention; FIG. 11 is a two-part drawing of which FIG. 11a illustrates an actual part, while FIG lib illustrates a layered paper mold designed for that part; FIG. 12 includes FIG. 12a and FIG. 12b, which are plan and elevation views, respectively, of a registration platform of the invention and FIG 12c, which is a plan view of a typical sheet of construction paper; FIG. 13 includes FIG. 13a and FIG. 13b, which are similar to FIGS. 12a and 12b, and illustrates the manner in which a sheet such as that illustrated by FIG. 12c may be positioned on a registration table of the invention; FIG. 14 includes FIGS. 14a and 14b, which are similar to FIGS. 13a and 13b, respectively, and illustrate a selected registration hole placement; FIG. 15 includes FIGS. 15a and 15b, which are similar to FIGS. 14a and 14b, respectively, and illustrate an alternative registration hole placement; FIG. 16 includes FIGS. 16a and 16b, which are similar to FIGS. 14a and 14b, respectively, and illustrate a partially constructed model; and FIG. 17 includes FIGS. 17a and 17b, which are similar to FIGS. 16a and 16b, respectively, and illustrate another partially constructed model. BEST MODE FOR CARRYING OUT THE INVENTION FIG. 1 outlines the operation of a typical embodiment of the invention. As shown, a commercial CAD system, designated generally 30, is configured to provide an input file in conventional STL file format. Software, such as that disclosed in the microfiche appendix, designated generally 32, operates on the Stereolithography ("STL") file to create a Hewlett Packard Graphics Language ("HPGL") plot file and to print out all of the pages. The pages (sheets) are registered in proper sequence, and are bonded and coated to create a physical object (model or pattern) in a post process, designated generally 34. Currently available CAD software packages capable of generating a solid model provide an output file which can be converted into an STL file format (a faceted representation of the model). The surface triangles of the STL format combine to approximate the surfaces of the model, as shown by FIG. 2a. The accuracy of a faceted representation depends upon the chord height selected for the CAD software. The chord height is the distance between an actual curve and the straight line approximation of this curve. The smaller the chord height, the more accurate the representation of the model. The minimum attainable chord height varies for each CAD software. There are many commercially available solid modeling CAD programs, such as AUTOCAD, CADKEY, and Pro/ENGINEER, that can create the STL file format. FIG. 2a shows an example of an STL representation of a solid model of an ignition key part 33 (FIG. 7). The software 32 (microfiche appendix) can read and display an STL file generated by any CAD program. The operator can change the orientation of a part by rotating it. The software 32 gives the maximum dimensions of the input part in the x, y, and z directions so that the operator can choose the best direction for slicing the part. After the software has finished slicing the whole object, each cross section (thick layer) is displayed on the screen so that the operator can verify that the axis of slicing minimizes the number of layers 36 and maximizes accuracy. FIG. 2b shows the part illustrated by FIG. 2a sliced in the x, the y, and the z directions. The slicing orientation resulting in the lowest number of layers 36 is usually preferred. Referring to FIG. 3, the software 32 (FIG. 1) automatically calculates and lays out the maximum number of layers 36 that can be represented on one construction sheet 38. The thick layers 36 are sliced into parallel thin slices 39 (the thickness of the construction sheet material) arranged on the sheet 38 beginning from the bottom to the top and then from the left to the right, until the entire sheet 38 is filled. Each sheet 38 of cross section slices 39 is sorted and converted to HPGL plot file format (32, FIG. 1), which is output to a sign making plotter (40, FIG. 1). The plotter cuts slices 39 of the part, and automatically adds registration holes 42 (FIG. 3) on each sheet. Each sheet 38 illustrated by FIG. 3 consists of two layers- a paper 43 held by adhesive 44 to a backing layer 46. Preferably, only the paper 43 is cut to produce a slice 39, leaving the backing 46 in tact. However, registration holes 42 are cut completely through the sheet 38. The operator has the option of choosing from several construction materials. The most common are readily available label paper and foam sheet materials. Once all the sheets 38 have been cut, they are mounted in order on a registration table, generally 50, as shown in FIG. 4. The sheets 38 are registered by means of the pins 52 inserted through appropriate registration holes 42 (FIG. 3). Stacking of the sheets 38 organizes the slices 39 carried by respective stacked sheets into reassembled layers, generally 36 (FIG 5). The sheets are usually stacked with the backing layer 46 up. As each sheet 38 is stacked, the backing layer 46 is peeled off (and excess construction layer 43 removed), leaving residual adhesive 44 on the upper surface of the registered slices 39. The slices carried by the next sheet 38 that is stacked are thus glued firmly to the previously stacked slices 39 in proper arrangement. As illustrated, the whole decomposed object is first recomposed into its component thick layers 36 (FIG. 5). These thick layers 36 may be separated and stacked, being positioned by a second set of registration holes 58 (FIG. 3) created by the software 32 to complete the construction of the solid object. After construction, the modeled (recomposed) parts are given a coating to increase their rigidity, to prevent layer delamination, and to cover areas where the adhesive 44 is exposed. This coating may comprise paint, acrylic coating or glue, and is typically applied by spraying techniques or by dipping the recomposed part in a coating material. A notable characteristic of the present invention is the opportunity it provides to evaluate the geometry of the part (See FIG. 7) being built and to decompose the part into a convenient number of thick layers 36, each capable of further slicing into a plurality of thin slices 39. By efficient layout of layers 36, a maximum number of slices 39 may be laid out on one sheet 38, as shown in FIG. 3. As illustrated, the part being built is small enough for eight layers 36 of slices 39, having the maximum dimensions of the part, to fit on a single sheet 38. This "hierarchical model decomposition" approach allows eight layers to be stacked simultaneously, greatly reducing build time. Another advantage of hierarchical model decomposition is its inherently efficient utilization of construction material. For example, if the part in FIG. 3 requires 70 slices 39 to build, but eight slices 39 fit on a single sheet 38, only nine sheets 38 are required, rather than the conventional 70 sheets. The nine sheets 38 may be stacked first, resulting in eight layers 36. The eight layers 36 may then be stacked in order. That procedure requires a total of 15 stacking iterations, rather than the 70 iterations which would otherwise be required. As the part is stacked, there are potentially unsupported overhangs, generally 60, as shown in FIG. 6a. If the overhang is large, and many layers are stacked on top of it, the inherent cantilever effect tends to bend the part at the overhang, as indicated in phantom 62. This problem is solved with hierarchical model decomposition, whereby a parting line 64 can be defined by the operator right at the overhang as illustrated in FIG. 6b. Often layers built from the bottom up, such as shown by FIG. 6a, develop overhangs 60. It is often preferable for such parts to be built upside down, as shown by FIG. 6b. Sometimes, it is preferable for only certain sections of a part to be built upside down, and others to be built right side up. These arrangements can be accomplished if the part, or a section of the part, is mirrored, so that the top faces down, and the parts are stacked with the top going down first, and the bottom going down last, as shown in FIG. 6b. This construction approach eliminates overhang and improves the stability of the part during construction. It is generally preferable for layers 36 to be organized such that smaller slices 39 are stacked on top of larger slices 39 during the layup procedure. EXAMPLES Several prototype parts were built following the system illustrated by FIG. 1 and utilizing the software disclosed in the microfiche appendix. The parts discussed in the following examples are shown in FIG. 7, and were built out of 0.0127 centimeters (0.005 in.) thick label paper. I. Screw driver handle The screw driver handle 70 shown in FIG. 7 was drawn in Silverscreen, a 3- D modeling software. This example demonstrates the advantages of hierarchical model decomposition and mirroring, both of which are provided by the software 32. The part 70 was made from paper construction material, utilizing 207 slices. Registering and bonding these slices sequentially would have been very tedious. The part was decomposed into 8 thick layers which were built simultaneously. The 207 slices were thus cut from 26 sheets, reducing the number of registration and bonding operations from 207 to 32. As can be seen from FIG. 7, any outside slice of the part 70 will inherently have very little surface area. To avoid creating overhangs (See FIG 6a), the software 32 mirrored the initial outer section. The thicker slices could then be layed up first. The mirroring action required the software 32 to reverse the location of the registration holes 58 created by the software. Hence, the mirroring was automatically corrected when the thick layers 36 were subsequently assembled. The total build time for this part was about 3 hours. π. Ignition key The ignition key 33, also shown in FIG. 7, was drawn in Pro/ENGLNEER. This example demonstrates the advantage of being able to define parting line(s) while decomposing the model. It also utilized hierarchical model decomposition. The need for building support blocks was eliminated by defining a parting line through the center of the overhanging portion of the key. This parting line avoided overhanging portions. The whole model was decomposed into 61 slices 39 organized into six thick layers 36. The total build time for this part was about 2 hours. m. Calculator This part (72, FIG. 7) was drawn in Pro/ENGINEER. The part was decomposed into 61 slices organized into 6 thick layers which were built simultaneously. Construction of this part presented a particular problem when registering the keyboard keys 73. The slices containing the key cross sections were stacked on top of the base slices. This arrangement caused the base which had its sticky side up and extra material around the keys to stick together. This problem was solved by either covering the exposed area on the base layer with a non stick surface or by peeling the unwanted material from each of the layers containing the key cross sections before bonding. The total build time for this part was about 3 hours. -l i¬ lt is often desirable to create a prototype that has significant physical properties not provided by the construction materials used to fashion patterns in accordance with FIG. 1. Those patterns can be converted to metal parts, either directly or following enhancements of the kind routinely followed by pattern makers more closely to match the specifications of a desired finished part. Conventional techniques exist to create metal parts from prototypes made of foam and paper. Investment casting, sand casting, and lost foam casting techniques may be ibllowed to produce metal parts from the patterns produced by this invention. IN. Sand casting Sand casting can be used to obtain metal parts from paper models constructed in accordance with this invention. FIGs 8a and 8b illustrate the manner in which the desired model is built from the CAD drawing 30 in two halves with each half 74 separated by a parting line 76 which is defined by the designer. As illustrated by FIG. 8a, two holes 80 are created on each of these pieces for registration. These parts are then coated with a suitable material to prevent contact between the adhesive surface of the part and the sand. Each half is then registered and bonded to the base 82 of the cope and the drag using two removable pins (not shown) provided on the base of each half through the holes 80. The standard sand casting procedure can then be followed by ramming sand in the cope and the drag with the runners and the pattern in place. After the ramming, the pattern can be removed from each of the two halves resulting in the required sand cavity. The cope and the drag can then be assembled and casts can be made. V. Investment casting Investment casting is usually used to create metal parts from prototypes made out of foam or wax. This process can be implemented on foam models constructed by the software 32 of this invention. As shown by FIG. 9, the desired part is prototyped from a CAD model using layers of foam. The prototype is then directly dipped into a slurry of refractory material until a thick ceramic coating is obtained. This mold is then heated, first in an inverted position at a temperature of 93°C to 191 ° (200°F to 375 °F) for about 12 hours, and then in the upright position at a temperature of 649°C to 1038°C (1200°F to 1900°F) to completely melt away the foam prototype and create a hollow ceramic shell. Molten metal can then be poured into the hollow portion to obtain the finished casting. VI. Lost foam (Evaporative pattern) casting Lost foam casting can be applied to obtain metal parts from models created by this invention as illustrated by FIG. 10. The desired prototype is first drawn in a CAD software. A sprue and a vent are then added to the model within the CAD software. The software 32 can then be utilized by an operator to build a foam model 84 from this drawing. This foam part is then placed in a flask 85 and covered with sand 86. Molten metal poured into the sprue 87 instantaneously evaporates the foam resulting in the metal filling the volume previously occupied by the foam. NH. Paper molds for plastic parts Prototype paper molds for parts drawn on the computer can be used to make parts from any room temperature molding material as shown by FIG. 11. Starting with a part 90, a mold 92 may be designed using Pro/Mold design, a module of Pro/ENGINEER. The mold 92 may be made up of two halves with a parting surface 94 that is defined by the designer. Two registration holes 96 are also created on each of these halves. The two pieces are built using procedures illustrated by FIG. 1 and the software of the microfiche appendix. They are then coated with a suitable material to prevent adhesion between the paper and the molding material. The two halves are then mounted on respective base pieces 98 for increased rigidity using the two removable pins provided on each of these base pieces and the holes created in the CAD system for accurate registration. The two pieces are then registered and put together, and can be used to create parts by room temperature molding. FIGS. 12-17 illustrate the operation of a system of this invention which consists of commercially available and custom elements arranged to provide a variety of functions. The elements of the system are as follows: 3D CAD Software: The system is compatible with any CAD software that is capable of generating a 3D model and converting it to standard Stereolithography format. Common packages that 5 have this capability are: CADKEY, Autocad, Pro-Engineer, and SilverScreen. Computer to operate software: The software (ZWSLICE) described in detail in the microfiche appendix is currently written in the DOS environment, 10 requiring a PC compatible computer. Sign making plotter: A suitable such device is the PNC-9000 made by Roland Digital. Other HPGL plotters with cutting capabilities are also considered to be suitable. 15 Construction material: The system works with adhesive backed sheets of material up to 1 mm in thickness. The material must be compatible with the cutting blade supplied by the plotter. For the Roland plotter, suitable materials are standard label paper available in 20 21.6 centimeters by 27.94 centimeters (8 1/2" by 11 ") by 0.0127 centimeters (0.005") thick sheets and adhesive backed polystyrene foam sheets available in 0.069 centimeters (0.027") thickness. Adhesive spray: 25 Preferred building technique requires that the first layer of the part be sticky on both sides. This requirement is satisfied by coating the top of the first layer with a commercial spray adhesive. ZWSLICE software: This software is used to generate cross sections from the model, create plot files, and organize the cutting and assembly process. ZWSLICE provides the following capabilities: Load and view Stereolithography format files (3D 5 models). Select layer orientation and preview part sliced in this orientation. Automatically decompose part into thick layers, and arrange to cover the full sheet of construction material. 10 Allow operator to choose whether each thick layer will be built from bottom up or top down. (Mirror function) Slice this array of thick layers into thin slices which are the same thickness as the construction material. Generate HPGL plot files for each sheet of construction 15 material including part cross sections (slices) and any necessary registration holes. Display each cross section individually. Display the complete plot file for each construction sheet. 20 Interact with operator to plot any or all of the sheets. Store plot files for future use. Registration system for alignment of layers: The registration system, generally 100, shown in FIG. 12 allows a variety of registration options: 25 Corner Box alignment. As shown by FIG. 13, if the construction sheets 38 are carefully aligned in the plotter, the cross sections will be accurately registered to the edges of the construction sheet. Sequential sheets are aligned by aligning two edges of each sheet with the guide rails 101, 102 of the 30 corner box, generally 104. Registration holes outside part. FIG. 14 illustrates an arrangement in which one or more holes 42 placed outside the part 106 can be used with guide pins 52 to register sequential sheets 38. Registration holes in part. FIG. 15 illustrates the manner in which cross section slice 39 alignment can be assured for parts having appropriate geometry by generating two registration holes 108 passing completely through each part. Sequential layers are guided by registration pins 110 extending from a pin plate 112 mounted in a recess in the platform 114, as shown. Surface coating material: After construction, the parts are given a coating to increase the rigidity of the parts, prevent layer delamination, and cover areas where the adhesive is exposed. Caφenter's glue thinned with tap water is useful for this puφose. To utilize this device, the operator begins with a 3D model generated with a 3D CAD software. The file is stored in Stereolithography format. Using ZWSLICE, the file is loaded and viewed. The operator is prompted to select a slice orientation, and subsequently the part is displayed, sliced in this orientation, to verify the operator's selection. Changes are allowed at any time. When the operator is satisfied, the program evaluates the build area required for the part and then determines how many of these areas can be fit onto a single sheet (or page) of construction material. The part is then automatically sliced into thick sections that occupy the maximum practical portion of surface area of the construction material. These thick sections are subsequently sliced into layers matching the construction material thickness, and a plot file is generated for each sheet of material required. Registration holes are automatically added to the plot file for sheet to sheet registration and for section to section (layer 36) registration. Each part cross section (slice 39) generated can be displayed to verify the intended result. The plot file (See FIG. 3) for each sheet of construction material can also be displayed. When the operator is satisfied with the displayed information, the construction sheets can be cut. ZWSLICE prompts the operator in the operation of the plotter to generate all or any one of the construction sheets. Ideally, the plotter cutting pen is adjusted so that a single pass of the cutter cuts through the construction material but not the backing material. Registration holes 42, 58, 108 are cut completely through the backing material; e.g. by effecting multiple passes of the cutter. The part is assembled on the build table by sequentially registering and bonding the layers. Each sheet 38 contains two registration holes 42 corresponding to the two permanent registration pins 42 on the build table 100. The first layer and the last layer may also contain registration holes 58, 108 for each section 36 of parts that have been decomposed into sections. The build process proceeds as shown by FIG. 16. The top of the first sheet is coated with spray adhesive, and the excess construction material is peeled from the backing sheet leaving only the part cross sections 120. This sheet is placed face up on the registration table 100 by carefully passing the registration pins 52 through the registration holes 42. The second layer 122 is placed on the registration table face down by passing the registration pins 52 through the registration holes 42. The second sheet 122 is pressed firmly against the first sheet 120 to insure that the adhesive bonds the two layers together. The backing layer of the second sheet 122 is carefully removed, leaving the second layer cross section on the registration table, bonded to the first layer cross section. The second layer 122 is now positioned adhesive side up ready to bond to the next layer 124. (It is sometimes advisable to remove the excess construction material from the second sheet before registering and bonding this sheet. This prevents adhesive from the first layer which may overlap the excess material on the second sheet from bonding to that material.) Subsequent layers are applied exactly as the second layer was applied. Care must be taken to insure that when the backing is peeled away the cross section remains bonded to the registration table and the part is not peeled off the build table. Parts that cover only a portion of the construction sheet can be sliced into thick sections 36 and assembled in a two step process. The first step proceeds as described in connection with FIG. 16, resulting in a construction sheet with several sections 125-128 adhered to its surface, as shown in FIG. 17. The second step of the assembly process proceeds as follows: When the last layer is applied, the backing material is not immediately removed. Because the part is being built in sections, it is important to note the orientation and order of the layers. ZWSLICE will display a building page that numbers the sections in order of lamination. These numbers may be marked on the upper surface backing material before the sheet holding the sections is removed from the registration table. The entire assembly, containing an upper sheet, part sections, and a lower sheet is removed from the registration table 100. The sections 125-128 are cut apart, retaining the proper registration holes with each section. Next, two registration pins 130 are threaded into the metal plate 112 in the center of the registration table. The spacing between the pins 130 should match that between the registration holes 132 on the sections 125-128. The portion of the backing sheet that does not contain registration holes is peeled away from section 125. This section is placed on the registration table by passing the registration pins 52 through the registration holes 132. This section is positioned backing side down. The backing sheet portion that does not contain registration holes is peeled away from section 126. This section is positioned on the registration table 100 by passing the registration pins 52 through the registration holes 132. This section is positioned backing side up. Section 126 should now be bonded to section 125. Sections 127, 128 and any subsequent sections are assembled just as section 126 was assembled. Reference herein to details of the illustrated embodiments is not intended to limit the scope of the appended claims, which themselves recite those limitations regarded as definitive of the invention. APPENDIX ZWSLICE1.CPP Shapemaker 1 software. Version 1.0 Copyright (c) 1995, University of Utah. All rights reserved. This is the main program which directs all the functions and subfunctions. This software is compiled and linked under the Borlandc C++ 3.1 enviroment. Writen by Zetian Wang Function Description 1) title (void); Generates a title on the screen. 2) printlogo(void) ; Puts the software logo on the screen. 3) load_file(void) ; Lists all the STL files in the current directory and allows the user to open the desired file. 4) display_rotate(void) ; Displays a shaded image, along with the slicing plane and the intersection of the two. . Also rotates the shaded image and the slicing plane. 5) enter_params(void) ,* The user inputs the slicing axis and thickness. 6) is_op_allαwable(char op); Controls each procedure that is allowable to the user. 7) menu(void); Outputs a menu. 8) slice_and_display(void) ; Slices the object and displays all slices. 9) display_slice (void) ,* Displays each slice individually and then shows the layout of slices on each sheet. 10) make_hpgl_stuff(void) ; Sorts the line file and converts it to HPGL file format. 11) print_all_pages(void) ,* Outputs the HPGL file to the plotter for cutting. 12) print_single_page(void) ; Outputs one single sheet to the plotter for cutting. 13) clean_up(void) ; Deletes all of the intermediate files (.In, .sr, and .hp files) . ******************************************** #include "menu.h" int main_state; int title(void) ,* void printlogo(void) ; int load_file(void) ; void display_rotate(void) ; void enter_params(void) ,* int is_op_allowable(char op); char menu(void) ; void slice_and_display(void) ; int make_hpgl_stuff (void) ,* void print_all_pages(void) ; void print_single_page(void) ,* void clean_up(void) ; char part_name[50], axis,c; float thickness; int i,count_slice,showpage,* /***************************************************************************** * This function generates a graphics title on the screen . int title(void) { int gdriver = DETECT, gmode, errorcode; int i,x,y,color,fill,xasp,yasp; char head[l = "Manufacturing lab"; char title [] = "Shapemaker I ",- char end[] = "press a key to continue"; initgraph(tgdriver, &gtnode,"."),* errorcode = graphresult0 ,* if (errorcode != grOk) /* an error occurred */ { printf("Graphics error: %s\n", grapherrormsg(errorcode)) ,* printf("Press any key to halt:"); getch() ; exit(l); /* return with error code */ } setbkcolor(BLUE) ,* rectangle(0,0,getmaxx() ,getmaxy() ) ,* setcolor(YELLOW) ; settextjustify(LEFTJTEXT,TOP_TEXT) ; settextstyle(TRIPLEX_FONT,HORIZ_DIR,7) ; outtextxy( (getmaxx0 -textwidth(title) ) /2,getmaxy0/3,title) ; settextstyle(TRIPLEX_FONT,HORIZ_DIR,5) ; outtextxy( (getmaxx()-textwidth(head) )/2,getmaxy0/2,head) ; settextjustify(LEFTJTEXT,BOTTOM_TEXT) ; settextstyle(TRIPLEX_FONT,HORIZ_DIR,2) ; outtextxy( (getmaxx() -textwidth(end) )/2,getmaxy{) -10,end) ,* getch() ,* closegraph() ,* return 0; } /******************************************************************************* This function puts the software's logo on the screen. void printlogo() { clrscr() ,* printf("\n") ,* printf(" \n") printf("\n") ,* printf(" ZWSLICE 1.0\n") ,* printf("\n") ,* printf(" \n") printf("\n") ,* printf("\n") ; if(main state<2) { " printf("\n") printf("\n") printf("\n") else { printf (" Part: %s\n" , file_name) ; printf (" Axis: %c\n" ,axis) ; printf (" Slice Thickness: *1.3f mm\n",thickness) ; printf (" Slice Number: %d ",count_slice) ; printf ("\n") ,* printf ("\n") ,* printf ("\n") ,* } /♦♦♦A************************************************************************** This function 1) Lists STL files in the current directory 2) Changes directory and driver 3) Loads files ******************************************************************************* int load fileO { char ch; int ins,* clrscr() ; while(ch!='a' &&ch!='b') { clrscr() ,* printf ("\nPress a to list .stl file. Press b to enter file name. Press q to e: ch«getch() ,* if (ch=='q' I I ch=='Q') return 0; } switch(ch) { case 'a' : case 'A' : system("dir *.stl/w"); case 'b' : case 'B' : ins=read_stl 0 ,* if(ins==-ι) return 0; object_size () ,* draw_stl wire{); printf ("\n Object Size:\tx=%f (mm)\ty=Vf (mm) \tz= f (mm) \n",xmax, ymax, zmax) ,* printf ("\n") ,* printf ("Press any key to continue"); getch() ,* main_state=l,* return 0; / }****************************************************************************** * This function 1) Displays: a shaded image with coordinate axes and slicing plane, along with the intersection of the two 2) Rotates: a) the shaded image b) the slicing plane ******************************************************************************** void display_rotate() return; _ _ } /****************************************************************************** This function allows the user to input slicing axis and thickness ****************************************************************************** ** void enter_params() char ch, mpstring[80] ; clrscr() ; printlogo() ,* axis*0; while(axis!='x' && axis!='y' && axis!='z') { printf("\nEnter axis normal to the slices (x,y, or z) : "),* scanf ("%s",tmpstring) ; axis=tmpstring[0] ; . < thickness=0.0; while(thickness<=0.0009 || thickness>=5.01) printf ("\nEnter the thickness of the slices (in mm): "); printf("\na Paper thickness (0.123mm)"); printf("\nb Form thickness (0.475mm)"); printf ("\nc User inpute "); printf ("\n\n") ; ch=getche() ,* switch(ch) { case 'a' : case 'A' : thickness=0.123; break; case 'b' : case 'B' : thickness=0.475,* break; case ' c' -. case 'C : printf("\nEnter the thickness of the slices (in mm): "),* scanf("%s", mpstring) ; sscanf(tmpstring, "%f",tkthickness) ; break,* . ' printf("\n\n") ,* if(axis=='x' ) count_slice=(int) ( (xmax-xmin) /thickness) ; if(axis«='y' ) count_slice=(int) ( (ymax-ymin) /thickness) ; if{axis=='z' ) Count_slice=(int) ( (zmax-zmin)/thickness) ; main state=2; } " /********* * ********** * ***** * ***** * **** * * * ******** ** * * * * ** ** ** ** **** * * *** * ****** This function controls each procedure that is allowable to the user. int is op allowable(char op) { " " if (op=='l' ) return 1; if(op=='8') return 1; if(op=='9') return 1; if(op=='0') return 1; if (main_state>=l && op=='2') return 1; if (main_state>=2 && op=='3') return 1; if (main_state>=3 && op=='4') return 1; if(main_state>=4 && op=='5') return 1; if (main_state>=5 && op=='6') return 1; if (main_state>=5 && op=='7') return 1; return 0; /}****************************************************************************** 4 This function outputs an operation menu, hightlighting the operation that follows the last one completed. ******************************************************** * ********************** * char menu() { char c; if (main_state==0) j textcolor(14) ; cprintf(" 1 - Load STL file \r\ if (main_state!=0) { textcolor(7) ; printf (" 1 - Load STL file \n" if (main_state==l && is_op_allowable('2' ) ) {textcolor(1 ) ; cprintf (" if(is_op_allowable('2' ) && main_state1=1) {textcolor(7) ; printf(" if(main_state==2 && is_op_allowable{'3' ) ) {textcolor(14) ,* cprintf (" if(is_op_allowable('3' ) && main_state!=2) {textcolor(7) ,* printf (" if (main_state==3 && is_op_allowable('4' ) ) { extcolor(14) ,* cprintf (" if(is_op_allowable('4' ) && main_state!=3) {textcolor(7) ; printf (" 4 if (main_state==4 && is_op_allowable('5' )) {textcolor(14) ; cprintf (" if(is_op_allowable('5' ) && main_state!=4) {textcolor(7) ,* printf(" if(main_state==5 && is_op_allowable('6' )) (textcolor(14) ; cprintf (" if(is_op_allowable('6' ) && main_state!=5) {textcolor(7) ; printf (" if(is_op_allowable('7' ) ) printf(" 7 - Print a single page\n"),* textcolor(7) ; printf(" 8 - DOS shell\n"); printf(" 9 - Clean up\n"); printf (" 0 - Quit\n"); do { c=getch() ,* while(!is_op_allowable(c) ) ; return c; } /♦♦♦A*************************************************************************** This function slices the object and generates a series of .In files. It also displays several slices in 3D view. ******************************************************************************** void slice and display() { " " int pages,showpage,* clrscr() ; printf ("Slicing the part...\n\n") ,* if ( axis=='x') { slice_all (xmin,xmax,thickness) ; draw all slice(xmin,xmax, hickness) ; } " " else if ( axis=='y') slice_all (ymin,ymax,thickness) ,* draw_all_slice (ymin,ymax,thickness) ; else if ( axis=='z') { slice_all (zmin,zmax,thickness) ; draw all slice(zmin,zmax,thickness) ; } " " printf ("\n\n Done! Press any key to continue"); getch() ; main state=3; }/******************************************************************************* This function 1) Displays each slice and the layout of slices on each sheet. 2) Flips some slices according to user input. ******************************************************************************** void display_slice{) int pages; int gdriver = DETECT, gmode; clrscr() ; pages=count_pages() ; initgraph(&gdriver, tgmode, "."); setviewport (0,0,getmaxx() ,getmaxy0,0); for(i=l;i<=number of slices;i++) { ~ ~ clearviewport () ,* c=draw_slice(i) ,* if(c=='q') break; } closegraph() ,* printf ("\nPress any key to display layout, Press q to quit\n"); getch () ; initgraph ( fcgdriver , &gmode , " . " ) ; setviewport (0 , 0 , getmaxx ( ) , getmaxy ( ) , 0 ) ; f or (i=l ; i<=pages ; i++) { • clearviewport() ; c=lay_out(i) ,* if(c=='q') break; closegraph() ; arrange_ment () ,* flip_slice() ; printf("\n\n Done! Press any key to continue"),* getch() ; main state=4; / }♦♦♦♦ " ♦A*********************************************************************** This function lets the user choose which sheet to mirror. Each line file is sorted so that the lines connect at the ends, forming a continuous loop. The line files are then converted into HPGL file format. ******************************************************************************** int make_hpgl_stuff() FILE *sizefile; int mirror,presee; char mirror_page,ch,* mirror=0; clrscr{) ,* printf(" Do you want to mirror paper?\n"),* printf(" Enter Y for yes, N for no."); ch=getch() ,* switch(ch) { case 'Y' : case 'y' : mirror=l; break; case 'N' : case 'n' : mirror=0; break,- case '\xlB' : default: mirror=0,* break; } if(mirror==l) { printf("\nEnter mirror choice\n"); printf(" f first pager mirror\n"); printf(" 1 last pager mirror\n") ; printf(" Hit Esc to escape\n"); ch=getch() ; switch(ch) { case 'F' : • case 'f' : mirror_page='f' ; break; case 'L' : case '1' : mirror_page='1' ,* break; case '\xlB' : default: break,* . ' clrscr() ,* printf("Sorting the lines...\n\n") ; presee=sort_line() ,* if(presee==-l) return -1; printf("\n\nConverting data to hpgl format...\n\n") ,* sizefile=fopen("objsize", "w") ; if ( axis=='z') { fprintf (sizefile, "%f %f",xmax-xmin,ymax-ymin) ; } else if ( axis=='x') { fprintf (sizefile, "%f %f",ymax-ymin,zmax-zmin) ; else if ( axis=='y') fprintf(sizefile, "%f Vf",xmax-xmin,zmax-zmin) ,* } fclose(sizefile) ; creat_hpgl (mirror,mirror_page) ; printf("\n\n Done! Press any key to continue"); getch() ; main_state=5; return 0; / }*********** * *************************************************************** * ** This function outputs the HPGL files to the plotter, printing one page at a time. ******************************************************************************* void print_all_pages char tmpstring[80] ,ch; int page; clrscr() ,* printf("\n\nPrinting all -fed pages...\n\n",Numpages) ,* for(page=1;page<=Numpages;page++) printf("\nlnsert the page -fed in the plotter and press p key...or press Est do { if ((ch=getch()) •== '\xlB') break,* else if (ch=='p') plot_out (page) ,* Jwhile <ch!='p'); printf ("\n\n Done! Press any key to continue"),* getch() ,* I /A***************************************************************************** This function only outputs one page of HPGL file to the plotter. A******************************************************************************- void print_single_page() char tmpstring[80] ,ch; int page; clrscr ; page-*-0; while(page<l | | page>Numpages) printf ("\n\nEnter tne page number to be printed (l-Vd) : ",Numpages); scanf {"%s",tmpstring) ; sscanf (tmpstring, "%d",&page) ; printf ("Page -fed will be plot\n", page); printf ("Insert page in the plotter and press p...or press Esc to escape"),* do { if ( (ch=getch() ) == '\xlB') break,* else if(ch=='p') plot_out (page) ,* Jwhile (ch!='\r'); printf ("\n\n Done! Press any key to continue"),* getch() ; } /******************************************************************************* This function deletes all intermediate (.In, .sr, and .hp) files. void clean up() { printf ("\n\nCleaning up intermediary files...\n\n") ; system("del *.hp") system("del *.ln") system("del *.sr") printf("\n\n Done! Press any key to continue"),* main_state=l,* getch() ,* /♦♦♦A*************************************************************************** This is the main function and only works when the user inputs numbers between 0 to 9. A function will be available only after the previous function has been completed successfully. If the user enters, 0 the software will quit. void main { char option; main state=0; title 0 do { printlogo ,* option=menu() ,* if(option=='l') load_file(); else if(option=='2' ) enter_params() ; else if (option=='3' ) slice_and_display() ; else if loption=='4' ) display_slice() else if (option=='5' ) make_hpgl_stuff () ; else if (option=='6' ) print_all_pages0 ,- else if (option=='7' ) print_single_page() ,* else if (option=='8' ) dos_shell ; else if (option=='9' ) clean_up(i ; clrscr() } while (option!='0' ) ,* ********************************************* * *********************** * **** * ** * *ι End of program. /****************************************************************************** SEARCH1B.CPP Shapemaker 1 Library function This subprogram reads the STL file and slices the solid object in either the x, y, or z direction by finding the cross sections where the slice planes intersect the object datafile. This software is compiled and linked under Borlandc C++ 3.1 enviroment. Written by Zetian Wang Function Description 1) read_stl (void) ,* Reads the STL file from a CAD program. Saves the data file in x,y,z coordinates. 2) object_size (void) ,* Finds the object size (maximum dimensions in the x, y, and z directions) . 3) slice_all (h_bot,h_top,dh) ,*Finds the number of slices needed and generates the slice plane. 4) get line (slice h,count) ; Finds the intersection between the slice plane and the object. Saves all line sections into .In files (with xl, yl, x2, y2 format) . 5) draw_stl_wire (void) ; Reads the STL file and generates a 3D wireframe image. 6) draw_all_slice (h_bot,h_top,dh) ; Draws thick slices of line files in 3D view. 7) draw_slice (int slice); Outputs each slice and the layout of each sheet on the screen. 8) arrange_ment (void) ,* Decomposes the object into thick slices and saves it to a data file. 9) flip_slice(void) ,* Flips the slice according to user input. 10) dos_sheel (void) ,* Temporarily goes to a DOS enviroment, where all DOS commands can be executed. 11) regist_hole (float x_size) ; Finds the horizontal distance between registration holes for the object. ■Sinclude "menu.h" unsigned int Number; void object_size (void) ; void getjline (float slicejh, int count); float paper_size_width,paρer_size_hight; float regist_hole (float x_size) ,* void slice_all (float h_bot, float h_top, float dh) ; void draw_stl_wire (void) ; void draw_all_slice (float h_bot, float h_top, float dh) ; void flip_parts (void) ; char draw_slice(int slice); int number_of_slices,num_file; char infile_name [15] , datafile_name[15] , file_name [15] ,data_file_name [15] ,* /A****************************************************************************** This function loads the STL file. The units of measure needed for the object are input (inch or mm or user_scale) . A data file (part.dat) is generated in x, y, z format. int read stl (void) { FILE *fptr; FILE *f ata; double x,y,z,unit; _ 2 g_ char temp [15] , ch; char namel [] = "vertex" ; /* attempt to open STL file for reading */ file_name[0]=0; infile_name[0]=0; data_file_name[0]=0; printf("\nEnter the STL file name to open (Don't use file extension, wing fc printf("\nor enter q to exit\n") ,* scanf("-fes",file_name) ; ch=file_name[0] ; if(ch=='q' I I ch=='Q') return (-1) ; sprintf(infile_name, "%s.stl", file_name) ; sprintf(data_file_name, "%s.old", file_name) ; while ( (fptr = fopen(infile_name, "r") )==NULL) printf ("\nCan't find %s file, please enter again\n", file_name ); printf ("\nor enter q to exit\n"); file_name[0]=0; infile_name[0]=0; data_file_name[0]=0; scanf("-fcs",file_name) ; ch=file_name[0] ,* if(ch=='q' I! ch=='Q') return (-1) ,* sprintf(infile_name, "%s.stl", file_name) ; sprintf(data_file_name, "%s.old", file_name) ,* } printf("\nPlease enter object unit"); printf("\ni: inch "),* printf("\nm.* mm ") ; printf("\nu: user-scale "); printf("\n\n") ; ch=getche() ,* switch(ch) { case 'i' : case 'I' : unit=25.40; break,* case 'm' : case 'M' : unit=1.0; break; case 'u' : case 'U' : printf("\nenter user-scale\n") ; scanf("Vlf", &unit) ,* break; default: unit=1.0; break; } Number=0; fdata = fopen(data_file_name, "w") ; do { fscanf(fptr, "%s",temp) ; if (strcmp(temp,namel)==0) { fscanf(fptr, "%lf%lf%lf",&x,&y,fcz) ,* fprintf(fdata, "%.7g\t%.7g\t%.7g\n",x*unit,y*unit,z*unit) ,* Number=Number+l; } } while (fgetc(fptr) !=EOF) ; printf("\n -fed triangular find", Number/3); fclose(fdata) ; fclose(fptr) ; return 0; } /****************************************************************** ************ , This function reads the data file (part.dat) and finds the object size (maximum dimensions in X, Y, and Z directions) . All the data will shift to positive coordinates with Xmin, Ymin, and Zmin reset to zero. ******************************************************************************* , float xmin,xmax,ymin,ymax,zmin,zmax; void object_size() int i; float x,y,z,x_new,y_new,z_new,x_min,y_min,z_min,x_max,y_max,z_max,* FILE *fdata, *sizefile, *data; xmin=50000; xmax=-100000 x_min=50000; x_max=-100000 ymin=50000; ymax=-100000 y_min=50000; y_max=-100000 zmin=50000; zmax=-100000 z min=50000; z max=-100000 if (( data = fopen(data_file_name, "r") )==NULL) printf("\n cannot open the file: %s\n",datafile_name) ,* else { fscanf (data, "-fef%f%f",fix,&y,&z) ; x_min=x,* y_min=y; z min=z,* printf ("\nFinding object size. Please wait...\n") ,* for (i=0; fscanf(data, "%f%f%f", &x,&y,tz) !=EOF; i++) { if (x<x_min) x_min=x; if (x>x_max) x_max=x; if (y<y_min) y_min=y; if (y>y_max) y_max=y,* if (z<z_min) z_min»=z; if (z>z_max) z max=z; } rewind (data) ,* datafile_name [0] =o,* sprintf (datafile_name, "%s.dat", file_name) ,* if ((data = fopen(data_file_name, "r") )==NULL) printf ("\n cannot open the file: %s\n",data_file_name) ; exit (-1) ; } fdata = fopen(datafile_name, "w") ; for (i=0; fscanf (data, "%f%f%f",&x,&y,&z) !=EOF; i++) { x_new=x-x_min; y_new=y-y_min; z_new=z-z_min,* fprintf (fdata, "%.7g\t%.7g\t%.7g\n" ,x_new,y_new,z_new) ; } xmm=x_mιn-x_mιn,- xmax=x_max-x_mιn; ymin=y_min-y_min,* • ' ymax=y_max-y_min; zmin=z min-z min,* zmax=z max-z min; , "w") ,* ,xmax-xmin,ymax-ymin) ; ,ymax-ymin,zmax-zmin) ; ,xmax-xmin,zmax-zmin) ; fclose(data) ; } } ****************************************************************************** This function finds the number of slices and generates the slice plane. *******************************************************************************/ int count; void slice_all (float h_bot, float h_top, float dh) int i; int num_slice; float slice_h; num_slice= (int) ( ( h_top - h_bot)/dh); number_of_slices=num_slice,* num_file = num_slice ; printf (" The num_slice is %d" ,num_slice) ; if ( z3>0 ) { n2=fabs (z2) ; n3=fabs(z3) ; x= (n2*x3+n3*x2) / (n2+n3) ; y=(n2*y3+n3*y2)/(n2+n3) ; fprintf(fline, "\n%.7g\t%.7g" ,x,y) ; nl=fabs(zl) ; n3=fabs (z3) ; X=(nl*x3+n3*xl)/(nl+n3) ; y=(nl*y3+n3*yl)/(nl+n3) ; fprintf (fline, "\t%.7g\t%.7g",x,y) ; } } fclose (fdata) ; fclose (fline) ; return,* / }************** ************** * * *** *********** ********************** ******* ** *** * This function reads the data file and generates a 3D wireframe picture. The object is scaled and centered to fit the screen. ******************************************************************************** void draw stl wire(void) { " " int i,poly[8] ,x,y; char ch; float xl, 2,x3,yl,y2,y3,zl,z2, z3,s,si,s2; float dy,dz; int gdriver = DETECT, gmode, errorcode; FILE *fdata; /* initialize graphics mode */ initgraph(£*gdriver, &gmode, "C:\\borlandc\\bgi") ; /* read result of initialization */ errorcode = graphresult () ,* if (errorcode != grOk) /* an error occurred */ { printf("Graphics error: %s\n", grapherrormsg(errorcode) ) ; printf("Press any key to halt:"); getch() ,* exit(-l); /* return with error code */ } if (( fdata = fopen(datafile_name, "r") )==NULL) printf("\n cannot open the file: %s\n",datafile_name) ; else { dy=0.866*0.3; for ( i=l,count=l; i<=num file; i++,count++ ) { slice_h = (float) (h_bot + i*dh) ; getJLine(siice_h,count) ; clrscr() ; printf ("Slicing layer d", i ); } } ******************************************************************************* This function finds the intersection between data file and slice plane. It saves all the intersections in line files (.In) with line segement format (xl, yl, x2, y2) . ******************************************************************************** void get_line (float slice_h,int count) { int l,check; double x,y,xl,x2,x3,yl,y2,y3,zl,z2,z3; double nl,n2,n3; FILE *fdata; FILE *fline; char string[25]; char extension[] = ".In"; itoa(count, string,10); strcat (string,extension ),* fdata= fopen(datafile_name, "r") ; fline = fopen( string ,"w"); for(i=0; i<Number/3,*i++) { if (axis=='x') { fscanf (fdata, "%lf-felf lf",&zl,&xl,&yl) fscanf (fdata, "*lf-felf-felf",&z2,&x2,&y2) fscanf (fdata, "-klf-felf-felf",tz3,fcx3,&y3) } else if ( axis=='y') fscanf (fdata, " %lf%lf-klf " , tocl, &zl , &yl) fscanf (fdata, "-fclf%lf-felf " , S-x2 , &z2 , &y2) fscanf (fdata, "%lf %lf %lf " , tx3 , £iz3 , &y3 ) } else if ( axis=='z') { fscanf (fdata, "%lf*lf*lf",&xl,&yl,&zl) fscanf (fdata, "-klf%lf%lf",tx2,&y2,iz2) fscanf (fdata, "%lf%lfVlf",&x3,&y3,&z3) } zl= zl - slice_h; z2= z2 - slice h; z3= z3 - slice_h; check =1 ; if ( zl>0 S S Z2 >0 S z3 >0 ) check = 0 ; if(zl<0 && z2<0 && z3<0) check = 0; if (check==l) { if ( zl==0) /* i) { check for condition of zl=0 */ if( z2 == 0 ) { if ( z3 != 0 ) fprintf (fline, "\n%.7g\t%.7g\t%.7g\t%.7g",xl,yl,x2,y2) ; if ( z2 > 0 ) ' ' { if ( z3<=0 ) { n2=fabs(z2) ; n3=fabs(z3) ; x = (n2*x3+n3*x2)/(n2 + n3) ; y = (n2*y3+n3*y2)/(n2 + n3) ; fprintf(fline, "\n%.7g\t%.7g\t%.7g\t%.7g",xl,yl,x,y) ; if ( z2 < 0 ) { if ( z3 >= 0) { n2=fabs(z2) ; n3=fabs(z3) ; x = (n2*x3+n3*x2)/(n2 + n3) ; y = (n2*y3+n3*y2)/(n2 + n3); fprintf(fline, "\n%.7g\t%.7g\t%.7g\t .7g",xl,yl,x,y) ; } } } /* 2) check for condition of zl > 0 */ if ( zl>0 ) { if( z2==0 ) { if (z3<=0 ) { nl=fabs(zl) ; n3=fabs(z3) ; x=(nl*x3+n3*xl) /(nl+n3) ; y=(nl*y3+n3*yl) /(nl+n3) ,* fprintf(fline, "\n%.7g\t%.7g\t%. g\t%.7g", 2,y2,x,y) ; if( z2>0 ) if ( z3<0 ) { nl=fabs(zl) ; n3=fabs(z3) ; x=(nl*x3+n3*xl) / (nl+n3) ,* y=(nl*y3+n3*yl) /(nl+n3) ; fprintf(fline, "\n%.7g\t%.7g",x,y) n2=fabs(z2) ; n3=fabs(z3) ,* x=(n2*x3+n3*x2) / (n2+n3) ,* y= (n2*y3+n3*y2) / (n2+n3) ; fprintf (fline, "\t%.7g\t .7g",x,y) } if( z2<0 ) { if ( z3==0 r { fprintf (fline, "\n%.7g\t%.7g",x3,y3) ; nl=fabs(zl) ; n2=fabs(z2) ; x=(nl*x2+n2*xl) / (nl+n2) ,* y= (nl*y2+n2*yl) / (nl+n2) ,* fprintf(fline, "\t%.7g\t%.7g",x,y) ; else if ( z3>0 ) { nl=fabs(zl) ; n2=fabs(z2) ; x=(nl*x2+n2*xl)/(nl+n2) ; y=(nl*y2+n2*yl) /(nl+n2) ; fprintf (fline, "\n .7g\t%.7g",x,y) ,* n2=fabs(z2) ,* n3=fabs(z3) ,* x= (n2*x3+n3*x2)/(n2+n3) ; y=(n2*y3+n3*y2) /(n2+n3) ; fprintf(fline, "\t%.7g\t%.7g",x,y) ,* else { nl=fabs(zl) ; n2=fabs(z2) ; x=(nl*x2+n2*xl)/(nl+n2) ; y=(nl*y2+n2*yl)/(nl+n2) ; fprintf(fline, "\n%.7g\tV.7g",x,y) ,* nl=fabs(zl) ; n3=fabs(z3) ; x=(nl*x3+n3*xl) /(nl+n3) ; y=(nl*y3+n3*yl)/(nl+n3) ; fprintf(fline, "\t%.7g\t%.7g",x,y) ; ) check for condition of zl<0 if ( zl<0 ) { if ( z2==0 ) { if (z3 >= 0 { fprintf (fline, M \n .7g\t%.7g",x2,y2) ; nl=fabs(zl) ,* n3=fabs(z3) ; X=(nl*x3+n3*xl)/(nl+n3) ,* y=(nl*y3+n3*yl)/(nl+n3) ; fprintf(fline, "\t%.7g\t%.7g",x,y) ; } } if ( z2>0 ) { if ( z3==0 ) { fprintf(fline, "\n%.7g\t%.7g",x3,y3) ; nl=fabs(zl) ,* n2=fabs(z2) ; x=(nl*x2+n2*xl)/(nl+n2) ; y=(nl*y2+n2*yl) / (nl+n2) ,* fprintf (fline, "\t%.7g\t%.7g",x,y) ; } else if ( z3>0 ) { nl=fabs(zl) ; n2=fabs(z2) ; x=(nl*x2+n2*xl)/(nl+n2) ,* y=(nl*y2+n2*yl) /(nl+n2) ,* fprintf (fline, "\n%.7g\t%.7g",x,y) ,* nl=fabs(zl) ; n3=fabs(z3) ; x=(nl*x3+n3*xl)/(nl+n3) ; y=(nl*y3+n3*yl)/(nl+n3) ,* fprintf(fline, "\t%.7g\t%.7g",x,y) ,* else { nl=fabs(zl) ; n2=fabs(z2) ; x=(nl*x2+n2*xl) / (nl+n2) ,* y=(nl*y2+n2*yl)/(nl+n2) ; fprintf(fline, "\n%.7g\t%.7g » ,x,y) ; n2=fabs(z2) ; n3=fabs(z3) ; x=(n2*x3+n3*x2)/(n2+n3) ; y=(n2*y3+n3*y2)/(n2+n3) ,* fprintf(fline, "\t%.7g\t%.7g",x,y) ; if ( z2<0 ) dz=0.5*0.3,• sl=0.0; s2=0.0; S=0.0; if( (ymax-ymin) >= (zmax-zmin ) && (ymax-ymin) >= (xmax-xmin)) sl= (getmaxx0/ (ymax-ymin) ) ; s2= (getmaxy()/(zmax-zmin) ) ,- if(sl>=s2) s = s2*0.85; else s = sl*0.85; } else if ( (zmax-zmin) >= (ymax-ymin) && (zmax-zmin) >= (xmax-xmin)) sl= (getmaxx()/(ymax-ymin) ) ; s2= (getmaxy0/(zmax-zmin) ) ,* if(sl>=s2) s = s2*0.85; else S = sl*0.85; } else if( (xmax-xmin) >= (ymax-ymin) && (xmax-xmin) >= (zmax-zmin)) sl= (getmaxx()/(xmax-xmin) ) ; s2= (getmaxy0/(ymax-ymin) ) ; if(sl>=s2) s = s2*0.85; else s = sl*0.85; } setviewport(0,0,getmaxx() ,getmaxy0,0); setbkcolor(1) ,* setcolor(14) ; if (((xmax-xmin) <= (zmax-zmin)) || ((xmax-xmin) <=(ymax-ymin) ) ) { for (i=l; i<Number/3 ,*++i) { fscanf(fdata, "%f%f-fef",&xl,&yl,&zl) fscanf(fdata, "%f%fVf",&x2,&y2,&z2) fscanf (fdata, "%f%f%f",&x3,&y3,&z3) (ymax+ymin)/2) (getmaxx()/2) ) (ymax+ymin)/2) (getmaxx()/2) ) (ymax+ymin)/2) (getmaxx0/2)) (zmax+zmin)/2) (getmaxyO/2)) (zmax+zmin)/2) (getmaxy0/2) ) (zmax+zmin)/2) (getmaxy0/2) ) line(yl,zl,y2,z2) line(y2,z2,y3,z3) line(y3,z3,yl,zl) } } else { for (i=l; i<Number/3 ,*++i) { fscanf(fdata, "%f%f%f",&χi,&yl,&zl) fscanf (fdata, "%f%f%f",&x2,&y2,&z2) fscanf(fdata, "%f%f%f",&x3,&y3,&z3) xl= (s*((xl)- (zl-zmin)*dy - (xmax+xmin) /2) (getmaxx() /2) ) x2= (s* ( (x2) - (z2-zmin)*dy - (xmax+xmin)/2) (getmaxx() /2) ) x3= (s*{ (x3)- (z3-zmin)*dy - (xmax+xmin) /2) (getmaxx0 /2) ) yl= (s* ( (yl) - (zl-zmin)*dz - (ymax+ymin)/2) (getmaxy0/2) ) y2= (s* ( (y2) - (z2-zmin) *dz - (ymax+ymin) /2) (getmaxy0 /2) ) y3= (s* ( (y3) - (z3-zmin)*dz - (ymax+ymin)/2) (getmaxy0 /2) ) line(xl,yl,x2,y2) line(x2,y2,x3«y3) Iine(x3,y3,xl,yl) } } } /* clean up */ getch() ,* closegraph() ,* return ,* }******************************************************************************* This function reads the line files and outputs several line files in 3D format. The entire picture is scaled and shifted to the center of the screen. ******************************************************************************* * void draw all slice( float h bot, float h top, float dh ) { " " int i,j,num; float xl,x2,yl,y2,zl,z2,si,s2,s,y; float dy,dz,h; float xl,xr,yt,yb,sx,sy,snew,delt_x,delt_y; int gdriver = DETECT, gmode; FILE *fline; char string[35],* char extension!] = ".In"; /* initialize graphics mode */ initgraph(&gdriver, igmode, "C:\\borlandc\\bgi") ; dy=0.866*0.3; dz=0.5*0.3; if ( axis=='z') { _ _ if (zmax>xmax && zmax>ymax) s=getmaxy ( ) / (zmax-zmin) ,* else { si = (getmaxy 0 / (ymax - ymin) ) ; s2 = (getmaxy ( ) / (xmax - xmin) ) ; if (si >=s2 ) s=s2 ; else s=sl ; , ' else if ( axis==' x' ) { if(xmax>ymax && xmax>zmax) s=getmaxy() /(xmax-xmin) ; else { si = (getmaxyO / (ymax - ymin)),* s2 = (getmaxy()/(zmax - zmin)),* if (si >=s2) s=s2; else s=sl; . ' else if ( axis=='y') if(ymax>xmax && ymax>zmax) s=getmaxy() / (ymax-ymin) ; else { si = (getmaxy()/(xmax - xmin)); s2 = (getmaxy() /(zmax - zmin)),* if (si >=s2) s=s2; else s=sl,* , ' setviewport(0,0,getmaxx() ,getmaxy0,0); setbkcolor(1) ; setcolor(14) ,* if(num_file<=10) num=l; else num= ceil(num_file/10) ; xl=25000.0; xr=-25000.0; yt=25000.0; yb=-25000.0; for ( i=l,*i<=num file; i+=num) { h=(float) (h_bot+i*dh) ,* itoa(i, string,10); strcat (string,extension ) ,* fline = fopen( string ,"r"),* for ( j=l ; j<=Number && fgetc(fline) !=E0F ,* j++) fscanf(fline, "*f%fVf%f", &xl ,&yl,4x2,ty2) ; yl= (s* ( (yl ) - (xl-xmin) *dy - (ymax+ymin) /2 ) + (getmax () /2) ) y2= (s* ( (y2 ) - (x2-xmin) *dy - (ymax+ymin) /2 ) + (getmaxx0 /2) ) zl= (s* ( (h) - (xl-xmin) *dz - (h_top+h_bot) /2 ) (getmaxyO /2) ) z2= (s* ( (h) - (x2-xmin) *dz - (h_top+h_bot) /2 ) (getmaxy0/2) ) if (xl>yl) xl=yl ; if (xl>y2 ) xl=y2 , if (xr<yl ) xr=yl ; if (xr<yl ) xr=yl , if (yt>zl) yt=zl ; if (yt>z2 ) yt=z2 , if (yb<zl) yb=zl ; if (yb<z2 ) yb=z2 ; } close{fline) sx= (xr-xl) /getmaxx() ; sy=(yb-yt)/getmaxy() ,* if(sx<=1.0 && sy<=1.0) snew=1.0; delt_x=(getmaxx() - " (xr+xl) ) /2.0 ; delt_y= (getmaxy0 - (yb+yt) ) /2.0 ; else { snew= ( (sx > sy) ? sx : sy) ; snew=1.0/snew; delt_x= (getmaxx() - (xr+xl) ) /2.0 ; delt_y= (getmaxy() - (yb+yt) ) /2.0 ; } for ( i=l;i<=num file; i+=num) { h= (float) (h_bot+i*dh) ; itoa(i, string,10); strcat (string,extension ); fline = fopen( string ,"r"),* for ( j=l ; j<=Number && fgetc(fline) !=EOF j++) fscanf (fline, "%f-fcf-fcf*f",txl,&yl,4x2,&y2) ; yl= ( (s* (yl- (xl-xmin) *dy - (ymax+ymin) /2) + getmaxx0/2) + delt_x) *snew; y2= ( (s* (y2- (x2-xmin)*dy - (ymax+ymin) /2) + getmaxx0/2) + delt_x) *snew ; zl= ((s*(h - (xl-xmin) *dz - (h_top+h_bot) /2) + getmaxy0/2) +delt_y) *snew z2= ((s*(h - (x2-xmin)*dz - (h_top+h_bot) /2) + getmaxy0/2) +delt_y) *snew line(yl,zl,y2,z2) ,* fclose (fline) ; } /* clean up */ getch() ,- closegraph() ; return ,* / }***************************************************************************** * This function draws single slices and single pages of layout. The last page will show the registration holes. All the images are scaled and centered to fit the screen. ♦♦♦A***************************************************************************/ char draw slice(int slice) { . int i; float xl,x2,xa,xb,yl,y2,ya,yb,zl,z2,za,zb,si,s2,s; float dy,dz; FILE *fdata; char slicefilename[15] ,c, ex [15] ; sprintf (text, "Slicing %d",slice) ; settextstyle(TRIPLEX_FONT,HORIZ_DIR,2) ; outtextxy( (getmaxxO -textwidth(text) ) /2,15,text) ; if ( axis=='z') { if ( (ymax-ymin) >= (xmax - xmin) ) s = (getmaxy0 /(ymax - ymin))*0.7; else if ( (ymax-ymin) < (xmax - xmin) ) { s = (getmaxxO /(xmax - xmin))*0.7; else if ( axis=='x') { sl=(getmaxx() /(ymax-ymin) ) ,* s2=(getmaxy()/(zmax-zmin) ) ,* if(sl>=s2) s=s2*0.9; else s=sl*0.9; } else if ( axis=='y') if( (xmax-xmin) >= (zmax - zmin)) { s = (getmaxxO/(xmax - xmin))*0.7; } else if( (xmax-xmin) < (zmax - zmin)) { s = (getmaxy() /(zmax - zmin))*0.7; . » sprintf(slicefilename, "-fed.In",slice) ; if (( fdata = fopen(slicefilename,"r") )==NULL) printf("\n cannot open the file: -ts\n",slicefilename) ; else { setbkcolor(l) ; setcolor(14) ; for (i=l; fgetc(fdata) !=EOF,*i++) { if { axis=='z') fscanf(fdata, "-fef%f%f%f",txl,tyl,&x2,&y2) ; xa=(s*(xl- (xmax+xmin) /2) + getmaxx0/2) xb=(s* (x2- (xmax+xmin)/2) + getmaxx0/2) ya=(s*(yl- (ymax+ymin)/2) + getmaxy0/2) yb=(s*(y2- (ymax+ymin)/2) + getmaxy0/2) line(xa,ya,xb,yb) ,* } else if ( axis=='x') { fscanf (fdata, "-fef%f-fef%f",&yl,&zl,&y2,&z2) ; ya=(s*(yl- (ymax+ymin) /2) + getmaxx()/2) ; yb= (s* (y2- (ymax+ymin) /2) + getmaxx0/2) za=(s* (zl- (zmax+zmin)/2) + + ggeettmmaaxxyy00//22)) zb= (s* (z2- (zmax+zmin) /2) + getmaxy0/2) line(ya,za,yb,zb) ,* } else if ( axis=='y') { fscanf (fdata, "%f%f%f%f",&xl,&zl,tx2,&z2) ,* xa=(s*(xl- (xmax+xmin)/2) + getmaxxO/2) xb= (s* (x2- (xmax+xmin) /2) + getmaxxO/2) za=(s* (zl- (zmax+zmin) /2) + getmaxy0/2) zb= (s* (z2- (zmax+zmin) /2) + getmaxy0 /2) line(xa,za,xb,zb) ,- } } c=getch() ,* fclose(fdata) ,- return c,* / }***************************************************************************** This function asks the user to input paper size (in landscopy format) . It then caculates how many columns and rows of slices can fit on a page, and how many sheets are needed to build a part. The slices are evenly arranged on the sheet. The space between each slice is also calculated. Presently we have only put a maximum of eight or nine slices on one sheet. *******************************************************************************/ float x_shift, y_shift,x_size,y_size,x_offset,y_offset,s,xoff,* float x_size_with_hole; int n=0,row,column,cond; int count_pages(void) int row2=0,column2=0,n2=0; float sl,s2; float net_wide, net_hight; char ch; if ( axis=='z') x_sιze=xmax-xmin; y_sιze=ymax-yπαn; else if ( axis=='x') .x_size=ymax-ymin; y_size=zmax-zmin; else if ( axis=='y') x_size=xmax-xmin; y_size=zmax-zmin; } printf("\nPlease enter the paper size"); printf("\na: width=ll(in) height=8.5 (in) ") ,* printf("\nb: width=12(in) height=9 (in)"),* printf("\nc: other size\n"); ch=getche() ,* switch(ch) { case 'a' : case 'A' : paper_size_width=280.0,* paper_size_hight=215.0; break; case 'b' : case 'B' : paper_size_width-=300.0,* paper_size_hight= ' 230.0; break,- case ' c' : case 'C : printf ("\nenter paper width in inch)\n"); scanf("%f", &paper_size_width) ; paper_size_width=25.4*paper_size_width; printf("\n enter paper height in inch\n"),* scanf("-fef", &paper_size_hight) ,* paper_size_hight=25. *paper_size_hight; break,* default: paper_size_width=280.0,* paper_size_hight=215.0,* break; } s=0.0; sl=getmaxx()/paper_size_width; s2=getmaxy()/paper_size_hight; row=0; x_shift=0; column=0; y_shift=0; if (si >= s2) { s=s2; } else S=Sl; cond=debug; if(cond==0) { xoff=10.0; net_wide=paper_size_width - paper_side*2.0 ; net_hight=paper_size_hight - paper_bot - paper_top; x_size_with_hole=regist_hole(x_size) ; row2=(int) (net_wide /(x_size_with_hole+xoff) ) ; column2=(int) (net_hight / (y_size + offset)); if ( (row2 && column2) >=1) { if (row2*column2 >= 8) { if ((num file%8)==o ) { n=(int) (num file/8) ; } if((num file 8) !=0) { n = (int) ((num file/(8) )+l) ,* } if((row2 >= 2) && (column2 >= 4)) { row = 2; column = 4,* x_offset = ( net_wide - 2.0*(x_size_with_hole + xoff)); y_offset = ( netjhight - 4.0*y_size )/3.0; else if((row2 >= 4) && (column2 >= 2)) { row « ; column = 2; x_offset = ( net_wide - .0*(x_size_with_hole + xoff))/3.0 ; y_offset = ( net_hight - 2.0*y_size ) ,* else if((row2 >=1) && (column2 >=8)) { row = 1; column = 8; x_offset = ( net_wide - 1.0*(x_size_with_hole + xoff)) ,* y_offset = ( net_hight - 8.0*y_size )/7.0; x_shift = x_offset/2.0; else if((row2 >=8) && (column2 >=1)) { row « 8; column = 1; x_offset = ( net_wide - 8.0*(x_size_with_hole +xoff))/7.0 ; y_offset = ( net_hight - 1.0*y_size ) ,* y_shift = y_offset/2.0; } else if((row2 >=3) && (column2 >=3)) { row = 3; column = 3; x_offset = ( net_wide - 3.0* (x_size_with_hole +xoff))/2.0 ,* y_offset = ( net_hight - 3.0*y_size )/2.0; if ((num file%9)«=0 ) { n=(int) (num file/9) ; } if((num file%9) !=0) { n = (int) ((num file/(9))+l) > > } if (row2*column2 < 8 ) { if ( (num file-fe (row2*column2) )==0) { n2= (int) (num file/(row2*column2) ) ; } if ( (num file% (row2*column2) ) !=0) { n2=(int) ( (num file/(row2*column2) )+1) ,* } n=n2,* row = row2,* column = column2,* if((row>l) && (column>l) ) x_offset = ( net_wide - row* (x_size_with_hole+xoff )) /(row - l) ; y_offset = ( net_hight - column*y_size )/ (column - 1) ; f((row>l) && (column==l) ) x_offset = ( net_wide - row* (x_size_with_hole+xoff) ) /(row - l) ,* y_offset = ( net_hight - column*y_size )/ (column ),* y_shift = y_offset/2.0; if((row==l) && (column>l) ) x_offset = ( net_wide - row* (x_size_with_hole+xoff) ) /(row ) ; y_offset = ( net_hight - column*y_size )/ (column - 1) ,* x_shift = x_offset/2.0; printf ("\nEach sheet will contain -fed slices,%d rows and %d columns", row*colu printf ("\n%d pages are needed to construct the part",n); else printf ("\nPrototype size is too big for landscape\n") ,* } /* end of debug* * =0 */ printf("\n Press any key to continue"),- getch() ; Numpages=n; return n,* / }******************************* *** ******* **** * ***************** *** ***** * *** *** * This function records the decomposion information into a data file. A object is decomposed into thick slices. ******************************************************************************** void arrange nent () int i,j,n, fliping,* char flip; FILE *file; if( (file=fopen("slice.dat", "w") )==NULL) printf("\nUnable to open file to write"); for(i=l;i<=num_file; i+=Numpages) { n=l; for(j=i; n<=l;j+=Numpages) fprintf(file, "%d\t",j) ; if(j+Numpages >num_file) fprintf(file, "%d\n",num_file) ,* else fprintf(file, "%d\n",j+Numpages-1) ; n++; } } fclose(file) ,* / }A****************************************************************************** This function finds out whether the user wants to flip any slices. **************************************************************** * ****** * ******** void flip_slice() char flip; printf("Do you want to fliping the slice\n"); printf("Enter y for YES, n for NO\n"),* while(flip!='y' && flip!='n') { flip=getch() ; switch(flip) case 'n' : case 'N' : break,* case 'Y' : case 'y' : flip_parts() ,* break; /******************************************************************************* This function will flip the slices according to user input. void flip_parts0 FILE *fpl; FILE *fp,*fp2; int i,j,m,n,mn; int limit; int data0[20] ,datal[20] ,data2 [20] ; char flip,c,oldfile[20] ,temfile[20] ,input [80] ,* int tempi [20] ; if( (fp=fopen("slice.dat", "r") )==NULL) printf("\nUnable to open file to read") ; i*=0; do { fscanf(fp, "%d %d", &datal[i], &data2[i] ) ; i++; } while(fgetc(fp) !=EOF) ; fclose(fp) ; limit=i-l; printf("\nStack Number "),* for(j=0;j<i-l; j++) dataO[j]=j; printf("\n-fed) : The slice is from %d to %d\n",data0 [j] , datal [j] ,data2 [j] ) printf("\nEnter stack number to flip with space betiween\n") ,* gets(input) ; printf("the string input is: -fes\n",input) ,* if( (fpl=fopen("slice.tmp", "w") )==NULL) printf("Unable to open slice.tmp to write"); printf("\nruning after get string"); fprintf (fpi, "%s",input) ; fclose(fpl) ; if((fp2=fopen("slice.tmp". "r") )==NULL) printf("\nUnable to open slice.tmp to read"); rewind(fp2) ,* for(i=0, ■ fscanf (fp2, "%d",itempl [i] ) !=EOF;i++) printf("\ntemp[-fed]=%d",i,tempi[i] ) ; fclose(fp2) ; for (j =0 ; j <limit ; j ++) for l int k=0 ; k<i ,* k++) { if (dataO [j ] ==templ [k] ) for ( n=datal [j ] ; n<=data2 [j ] ,*n++) sprintf(oldfile, "%d.ln",n) ,* sprintf (temfile, "%d.temp",n) ; rename(oldfile,temfile) ,* printf("\nslice n=-fcd",n) ; for ( m=datal [j ] , n=0 ;m<=data2 [j ] ;m++ , n++) mn=m+data2 [j] -m-n; sprintf (oldfile, "%d.temp",m) ; sprintf (temfile, "%d.ln",mn) ; rename(oldfile,temfile) ,* printf("\n slice m=-fed mn=%d",m,mn) ,* } } } } /♦A***************************************************************************** This function draws the layout of *-»ac* 1 -> sheet on the screen. On the last page, it also shows the registration holes. ******* * *** * * * *************** * ** * ***** ** *** * *** ** ******** ** ** * ** **** * ********** char lay ou (int page) { int 1=0,m=0,j=0,k=0,na,xcl,xc2,yc; FILE *fline; float xl,x2,yl,y2,xa,xb,ya,yb; char string[15] ,c,text[15] ; char extension!] = ".In"; cleardeviceO ; setbkcolor(l) ; setcolor(14) ,* rectangle(0,0,paper_size_width*s,paper_size_hight*s) ; sprintf(text, "page %d",page) ; settextstyle(TRIPLEX_FONT,HORIZ_DIR,2) ; outtextxy( (getmax O -textwidth(text) )/2,15,text) ; j=page; k-1; 1=0; na=n,* for ( m=j; m<=num_f"ile ,* m+=na) //&& k<=(column/2)// 1++; if (1== (column+D) { 1=1; k++; } itoa(m, string,10); strcat (string,extension ),- if ((fline = fopen(string, "r"))==NULL) printf("\n cannot open the file %s",string); break,* } while(fscanf(fline, "%f%f f%f", &xl,&yl,&x2,&y2) !=EOF) xa=(int) ( (k-1) * (x_size_with_hole+x_offset+xoff) *s+(xl+x_shift+paρer_side xb=(int) ( (k-1)* (x_size_with_hole+x_offset+xoff)*s+(x2+x_shift+paper_side ya=(int) ( (1-1)* (y_size+y_offset)*s+(yl-ymin+y_shift+paper_bot)*s ) ; yb=(int) ( (1-1) * (y_size+y_offset)*s+(y2-ymin+y_shift+paper_bot) *s ) ; line(xa,ya,xb,yb) ,* } if(cond==0) { if(j==n) xcl=(int) ( (k-1)*(x_size_with_hole+x_offset+xoff) *s+(paper_side+xoff/2.0+ xc2=(int) (xcl+x_size_with_hole*s) ; yc =(int) ( (1-1)*(y_size+y_offset)*s+(y_size/2.0+y_shift+paper_bot)*s ) ; /* draw the registration circle */ circle(xcl, yc, 3.175*s); circle(xc2, yc, 3.175*s); rewind(fline) ; fclose(fline) ; } c=getch() ,* return c; } /***************************************************************************** This function lets the user go to the dos shell to execute DOS commands. Entering "exit" will return the user to the program. ****************************************************************************** void dos shell (void) { printf("Press EXIT to return..."); /* go into the dos shell and enter exit to return */ system(getenv("COMSPEC") ) ,* / }******************************************************************************, This function will find the distance between registration holes for different object sizes. *******************************************************************************, float regist_hole(float x_size) int i; float hole_dist; float array[32] ={10.0,15.0,20.0,25.0,30.0,35.0,40.0, 5.0,50.0,55.0, 60.0,65.0,70.0,75.0,80.0,85.0,90.0,95.0,100.0,105.0,110.0, 115.0,120.0,125.0,130.0,140.0,145.0,155.0,170.0,175.0,185.0,205.0}; if(cond==0) { for(i=0;i<=31;i++) { if(array[i] > x_size) hole_dist=array[i+2] ,* break,* } else if(array[31] <= x_size) printf("\n WARNING : This part is too big to fit registration holes printf("\nthe hole_dist is %f", hole_dist) ,* else if(cond==l) { hole dist=x size; } getch() ,* return hole dist; } /*****************************************************************************» Jassor .cpp Shapemaker 1 Library function. This subprogram reads line files (.In) and sorts them into a sequenced line segement until the entire loop has been sorted and connected. If a double line is found, one of the two lines will be erased. After sorting, one sort file(.sr) will be generated in the line segment format (xl,yl,x2,y2) . To save the memory of the system a dynamic array has been used to store each line file. ******************************************************************************* #include "menu.h" int sort line(void) { unsigned int i,n,j,k=0,check,line_count; int count,m; FILE *fline,*flinel; , double xl,x2,yl,y2; char string[25] ; char stringl[25] ; char extension!] = ".In"; char extensionl [J =".sr"; for ( m=l,*m<=number of slices; m++) { ~ " count=0; itoa(m, string,10); itoa(m, stringl,10) ,* strcat (string,extension ),* strcat (stringl,extensionl) ; flinel= fopen( stringl, "w") ,* if ((fline = fopen(string, "r") )==NULL) printf("\n Can't find line file. Slicing object again!!"),* printf("\n Press any key to continue"),* getch{) ; return -1; } else { for (i=0;fscanf(fline, "%lf%lf*lf%lf",&xl,&yl,&x2,&y2) !=E0F ; i++) ,* rewind(fline) ; n=i+l; double ( *coord) [4] = new double [n] [4] ,* if(coord==0) { printf("Run out of memory"); exit(l) ; for (i=0,*fscanf(fline, "%lf%lf%lf%lf",&coord[i] [0] ,tcoordfi] [1] ,icoord[i] [2 for (k=0; k<i;k++) { for(j=k+l; j<=i; j++) if ( (coord [k] [0] ==coord [j ] [0] && coord [k] [1] ==coord [j ] [1] ) && (coord [k { printf("found double line 1"); coordtj] [0]=-1.0; count++; } else if ( (coordfk] [0] ==coord[j] [2] && coordfk] [1] ==coord[j] [3] ) && (cc printf ("found double line 2"); coord[j] [0]=-1.0; count ++; xl= coord [0] [0] ,*x2=coord[0] [2] ,* yl= coord [0] [1] ,*y2=coord[0] [3] ,* line_count=i ,* fprintf (flinel , "%lf \t%lf \t-felf \t%lf \n" , xl , yl ;x2 , y2) ; count++; do { check = 0; // test if two lines are connected to each other// for (j=l; xl!=x2 || yl!=y2 ;j++) if ( coordfj] [0] !=-1.0) if ( x2==coord[j] [0] && y2==coord[j] [1] ) fprintf (flinel, "%lf\t%lf\t%lf \t%lf\n" , coordtj] [0] , coordtj] [1] ,coord| x2 = coordtj] [2] y2 = coordtj] [3] coordtj] [0]=-1.0 check =1; count ++; } else if ( x2==coord[j] [2] && y2==coord[j] [3] ) { fprintf (flinel, "*lf\t-felf \t*lf\t%lf\n" , coord [j] [2] , coordtj] [3] , coord I x2 = coordtj] [0] ; y2 = coordtj] [1] ; coordtj] tO] =-1.0 ; check =1; count ++,* . ' if (j==line_count-l) Xif (check==0) printf("Problem, No connected line at point %f %f", x2,y2); else if (check==l) fprintf(flinel, "\nloop has been connected\n") ,* if ( count<line count ) { for (n=l;n<=line_count; n++) if ( coord [n] [0] ! = -l.0) { xl=coord[n] [0] ; x2=coord[n] [2] ; yl=coordtn] [1] ; y2=coord[n] [3] ; fprintf(flinel, " lf\t%lf\t%lf\t%lf\n",xl,yl,x2,y2) ; coordtn] [0]=-1.0; count++; break; »' while(count<line_count) ,* fclose(flinel) ; fclose(fline) ; delete []coord; clrscr() ,* printf("\nfile %d has been sorted",m); return 0; /*************************************************************************** HPGL A.CPP Shapemaker 1 Library function This subprogram reads the sorted line files and convert them into HPGL file format. One HPGL file contains all of the slices that fit onto one sheet. The registration holes will be cut three times and only cut on the mirrored page. Created by Zetian Wang. ♦♦♦♦A*************************************************************************, #include "menu.h" int Numpages; void creat_hpgl (int mirror,char mirror_page) int i, m,l, count_line=0,cond; int j,k,hole_page; int xli,x2i,yli,y2i,xcl,xc2,yc; float xc,xoff; FILE *flinel,*fhpgl\*filesize ; double xl,yl,x2,y2; char tempi [15] , temp2 [15] , temp3 [15] , temp4 [15] ,* char xcls [15] ,xc2s [15] ,ycs [15] ; char xls [15] ,yls [15] ,x2s ll5] , y2s [15] ; char string [15] ,- char stringl [15] ; char string2 [15] ; char extension !] = " . sr" ; char extensionl t ] = " . hp " ,* char name [] = "loop" ; char str[]="\033\056Y\033\056\100\073\063\072\033\056I20\073\07317\072\033\ char strl[]="\033\056Z\n"; cond-debug,* if(cond»l) xoff=1.0; else if (cond—0) xoff=10.0; for ( j=l; j<=Numpages,*j++) k-1; 1-0; itoa(j, stringl,10); strcat (stringl,extensionl) ; fhpgl= fopen( stringl, "w") ,* fprintf(fhpgl, "%s",str) ,- fprintf(fhpgl,"IN;IP;IW;LT;PU;PA0,0;SPl;VS20;\n") ; fprintf(fhpgl, "SPl;\n") ; for ( m=j,* m<=num_file ; m+=Numpages) 1++; if (1-= (column+1) ) { l-l; k++; } itoa(m, string,10); strcat (string,extension ); if ( (flinel = fopen (string. "r" ) ) ==NULL) printf("\n cannot open the file %s".string) ; break; } else rewind(flinel) ,* while (fscanf (flinel, "-fes%s-fes%s", tempi,temp2,temp3,temp ) !=EOF) count_line++; if (strcmp(tempi,name) ==0) { count line=0; } else { xl=atof(temp ' l) ,* yl=atof (temp2) ,* x2=atof (temp3) ; y2=atof (temp4) ; xli=(int) ( (k-1) * (x_size_with_hole+x_offset) *40.0+(xl + xoff+x_shift. x2i=(int) ( (k-1) * (x_size_with_hole+x_offset) *40.0+(x2 + xoff+x_shif ; if(mirror==l) { if(mirror_page=='f' ) /* mirrors first page */ hole_page=l; if(j==l) { xli= (int) ( (paper_size_width-2*paper_side) *40.0-xli) ,* x2i=(int) ( (paper_size_width-2*paper_side) *40.0-x2i) ,* } } else if(mirror_page=='l' ) /* mirrors last page */ hole_page=Numpages; if(j==Numpages) xli= (int) ( (paper_size_width-2*paper_side) *40.0-xli) ,* x2i=(int) ( (paper size width-2*paper side) *40.0-x2i) ,* else hole_page=Numpages; yli=(int) { (1-1)* (y_size+y_offset)*40.0+(yl + y_shift) *40.0 ); y2i=(int) ((1-1)* (y_size+y_offset)*40.0+(y2 + yjshift) *40.0 ) ,* itoa(xli,xls,10) ; itoa(x2i,x2s,10) ,* itoa(yli,yls,10) ; itoa(y2i,y2s,10) ; if(count line==l) { fprintf(fhpgl, "PU,*PA%s,%s,*\n",xls,yls) ,* fprintf(fhpgl, "PD;PA s,%s;\n",x2s,y2s) ; else fprintf(fhpgl, "PA%s,%s;\n",x2s,y2s) ; rewind(flinel) ; fclose(flinel) ; } fprintf(fhpgl, "PU;PA1200,6940CI127,*\n") ; fprintf(fhpgl, "PA1200,6940CI127,*\n") ; fprintf(fhpgl, "PA1200,6940CI127,*\n") ; fprintf(fhpgl, "PU.PA9200,6940CI127,*\n") ; fprintf(fhpgl, "PA9200,6940CI127;\n") ,* fprintf(fhpgl, "PA9200,6940CI127;\n") ; fprintf(fhpgl, "PU;PU;PAO,0,*") ; fprintf(fhpgl, "%s", strl); /* The following code generates the registration holes for the last page. The hole diameter is 1/4 inch */ if (j==hole_page) for(k=l;k<=row,*k++) { for(l=l;l<=column,*l++) { xc=( (k-1)*{x_size_with_hole+x_offset)*40.0+(xoff/2.0+x shift) *40 xcl=(int) ( (k-1)*(x_size_with_hole+x_offset)*40.0+(xoff72.0+x_shi xc2=(int)(xc + x_size_with_hole*40.ιθ " ); 40.0-xcl) ,* 40.0-xc2) ,* ze/2.0+y_shift)*40.0 ,* ,* } } fprintf(fhpgl, "PU;PU;PAO,0; fprintf(fhpgl, " s", strl) ; fclose(fhpgl) ,* clrscr{) ; printf ("\Create -fed HPGL file\n",j) ; } return ,* ***************************************************************************** PLOT1A.CPP Shapemaker 1 Library function This program will open an .hp file and output HPGL code to the plotter, using the hardware handshake between the computer and the plotter. Created by Zetian Wang Feb 4 1994 ***************************************************************************** #include "menu.h" void plot_out(int num) { char extension[] =".hp"; char string[25] ; char tmpstring[80] ,tmpstringl [80] ; itoa(num, string,10); strcat (string,extension ),* sprintf (tmpstring, "MODE COM2:9600,N,8,l,p >temp" ) ,* system(tmpstring) ; sprintf(tmpstringl, "COPY %s COM2: >temρ".string ) ; system("del temp"); system(tmpstringl) ; return ;

Claims: CLALMS What is claimed is: 1. In a rapid prototype system wherein an object is decomposed into a series of layers, and a physical model of that object is then constructed by creating a first such layer and thereafter sequentially creating additional such layers and bonding each such additional layer to a previous layer, the improvement which comprises: electronically decomposing said object into thick layers selected such that said thick layers may be positioned across an area corresponding to a sheet of construction material; electronically slicing said layers into cross sections the thickness of said sheet of construction material; plotting physical slices corresponding to said cross sections; forming said physical slices from said construction material; stacking said physical slices to construct said layers; and stacking said layers to recompose a physical model of said object. 2. An improvement according to Claim 1, further including the step of selecting said thick slices to minimize the number of layers required to recompose said physical model. 3. An improvement according to Claim 1 wherein said layers are defined by parting planes selected at regions of said object having relatively large dimensions, whereby to minimize overhangs during the step in which said physical slices are stacked to construct said layers. 4. An improvement according to Claim 3 wherein a said layer is constructed as a mirror image, whereby to increase the area of contact between said layer and a support structure upon which said layer is constructed. 5. A rapid prototype method, comprising: a. electronically decomposing an object into a series of relatively thick layers; b. electronically slicing said thick layers into cross sections the thickness of a sheet of construction material; c. plotting on sheets of said construction material physical slices corresponding to said cross sections; d. cutting said physical slices from said sheets of construction material; e. stacking said physical slices to construct said layers; and f. stacking said layers to recompose a physical model of said object. 6. A method according to Claim 5, wherein said sheets of construction material include a construction layer and a backing layer fixed to said construction layer with adhesive material and wherein said physical slices are cut from said construction layer, leaving said backing layer intact. 7. A method according to Claim 6, wherein: individual pluralities of said physical slices are distributed in corresponding patterns among an ordered set of said construction sheets; step c includes locating index positions on said sheets of construction material; and step d includes the placement of first registration holes at selected said index positions through said construction sheets; whereby to facilitate the precise registration of respective said pluralities of said physical slices carried by individual said construction sheets within said set of construction sheets when all of said construction sheets are stacked in the order of said set with registration pins inserted through said registration holes. 8. A method according to Claim 7, wherein second registration holes are located at second selected index locations to facilitate the precise registration of said layers when they are stacked to recompose said object. 9. A method according to Claim 5, wherein steps a, b, c and d are controlled by software equivalent to that of the appendix. 10. A method according to Claim 5, wherein: said construction material is in the form of flat sheets, each having a construction layer bonded to a backing layer; and step d is conducted such that said slices are cut through said construction layer, leaving said backing layer in tact. • * 11. A method according to Claim 10, wherein steps c and d are conducted such that registration holes are cut through said backing layer so that corresponding slices carried by respective said backing layers may be precisely registered during step e. 12. A method according to Claim 11, wherein steps a, b, c and d are controlled by software equivalent to that of the appendix. 13. A method according to Claim 7, wherein steps e and f are conducted on a build platform including first registration pins positioned to receive said first registration holes provided in said sheets. 14. A method according to Claim 13, wherein said build platform includes second registration pins positioned to receive second registration holes provided in said sheets, said second registration holes being located to facilitate the precise registration of said layers when they are stacked to recompose said object during step f .

Inventors: THOMAS CHARLES L, WANG ZETIAN, THOMAS, CHARLES, L., WANG, ZETIAN
Applicants: UNIV UTAH RES FOUND, UNIVERSITY OF UTAH RESEARCH FOUNDATION
Application year: 1996
Main classification: G06F19
IPC codes: B29C33, B29C67, G06F17