DEVICE AND METHOD FOR MARKING OPHTHALMIC LENSES AND MOLDS

Abstract: Device and method for accurately recreating verification markings with removable ink on progressive ophthalmic lenses and molds are provided. The device includes (a) a stage (38) which defines a coordinate system and which is adapted for receiving a lens or mold (36); (b) a magnifying device (32) for locating the reference marks on the lens or mold surface; (c) a computer (30) for storing coordinates from the platform wherein the coordinates represent the locations of two reference marks on the lens or mold surface; and (d) a pen device (34) adapted to be positioned over the surface of the lens or mold wherein the pen device is controlled by the computer for applying the verification markings in the lens or mold surface.

Description: DEVICE AND METHOD FOR MARKING OPHTHALMIC LENSES AND MOLDS FIELD OF THE INVENTION This invention is related to ophthalmic lenses and, in particular, to progressive power ophthalmic lenses in which a surface of the lens has distance, near and intermediate viewing zones with boundaries and contours which provide desired optical properties over the surface of the lens. The invention further relates to molds employed to fabricate progressive power ophthalmic lenses. MICROFICHE APPENDIX This document includes a microfiche appendix which contains one (1) microfiche having a total of 27 frames. BACKGROUND Methods of making progressive lens surfaces are known in the art and are described, for example, in U.S. patent Nos. 4,676,610, 4,806,010 and 4,838,675. Finished progressive lenses are typically made from progressive lens blanks, i.e. , optical bodies having a finished convex front progressive surface and an unfinished rear concave surface. The rear surface is normally finished to produce a lens which meets the wearer's prescription. The fitting of progressive lenses is more demanding than the fitting of conventional multifocals. In this regard, each progressive lens blank typically has two sets of markings, a temporary set and a permanent set, to assist in verification of power and in fitting the lenses to the patient's face. The temporary markings (or verification markings) usually consist of a fitting cross, which should fall within 2 to 3 mm from the center of the pupil, and a distance reference center mark and a near-reference center mark to use in checking the powers of the distance and near segment areas. Preferably, the temporary markings should be left on the lens until the position of the fitting cross can be verified on the patient's face. The permanent markings are typically semi-visible, and consist of two mesas (or slight elevations) on the surface of a lens that establish the horizontal line at the optical center of the lens. Some manufacturers also place their own identification mark and the power of the add near the semi-visible marks on the temporal side of the lens. In the event that the temporary markings are removed, they can be reconstructed by locating, marking, and placing the semi- visible marks over the manufacturer's centration chart, and then tracing the verification marks with a pen. If the lens is placed against a dark background and viewed with an intense light, the semi-visible marks can be seen more easily. Conventional methods of recreating the verification marks can be cumbersome and imprecise. SUMMARY OF THE INVENTION The present invention is based in part on the discovery that verification markings can be accurately reproduced on progressive ophthalmic lens with a computer aided device. In one aspect, the invention is directed to a method of applying verification markings on an ophthalmic lens which includes the steps of: providing a stage which is movable in a plane wherein positions of the stage are identifiable in a coordinate system; attaching the lens on the stage; locating two reference marks on the surface of the lens; identifying the positions of the two reference marks by coordinates; utilizing the coordinates of the two reference marks in a computer which includes a database containing the coordinates of verification markings for the lens; positioning the lens under a pen, preferably by moving the stage; calibrating the position of the pen; and applying the verification markings on the lens surface with movement of the stage and/or the pen wherein the movement of the stage and/or pen is controlled by the computer. In another aspect, the invention is directed to a device for applying verification markings on an ophthalmic lens which includes: a stage which defines a coordinate system and which is adapted for receiving the ophthalmic lens; a magnifying device for locating reference marks on the ophthalmic lens surface; a computer having a database containing the coordinates of verification markings for the ophthalmic lens; and a pen device adapted to be positioned over the surface of the ophthalmic lens wherein movement of the stage and/or pen device and stage are controlled by the computer for applying the verification markings on the ophthalmic lens surface. The inventive method and device are also applicable for applying verification markings on molds which are employed to cast progressive lenses. A feature of the invention is that the verification markings are reproduced using removable ink. In one embodiment, the computer database contains numerous patterns of verification markings that correspond to different ophthalmic lens designs. In this case, the technician employing the inventive device selects the desired pattern for production on the ophthalmic lens surface. In manufacturing ophthalmic lenses, the verification marks are originally printed onto the lens surface by transfer-pad printing. The present invention provides a convenient method of reinking the lens should one or more of these marks be removed prematurely. BRIEF DESCRIPTION OF THE DRAWINGS Figure 1 is a plan view of an ophthalmic lens blank with verification marks thereon; and Figure 2 is a drawing illustrating a device for restoring verification markings on ophthalmic lens blanks. DETAILED DESCRIPTION OF THE INVENTION Figure 1 illustrates a progressive power ophthalmic lens blank 10 that has semi-visible marks 22A and 22B and has printed verification reference markings on its surface. As used herein, the term "reference mark" or "semi-visible mark" shall refer to any substantially permanent mark on the progressive ophthalmic lens surface. Typically, two reference marks are present and the locations of the verification marks can be readily determined once the reference marks are located. The semi-visible marks typically comprise mesa-like structures on the lens surface which are created during the manufacturing of the lens. It is understood that the semi-visible marks can comprise any physical deformation that is created on the otherwise smooth surface of the lens. Progressive ophthalmic lenses are described, for example, in U.S. Patent Nos. 4,676,610, 4,806,010 and 4,838,675 which are incorporated herein. The verification markings include the major reference point 14 which is the geometric center of the lens, the axis line 24 which passes through the reference point and the semi-visible marks, lens fitting cross 16, distance power measuring circle (or distance horseshoe) 20, and the add power measuring circle (or near circle) 18. The distance horseshoe is for verifying the patient's distance prescription and the near circle is for verifying the add power. Since progressive lenses do not have discernable bifocal segments or demarcations, the verification markings help identify the precise positions of the near vision portion of the lens, for instance. The other verification marks are employed to guide the technician in properly edging the lens blank so that the contour of the finished lens as shown in silhouette 12 aligns the lens features properly within the frame of the eyeglass. Further, each properly finished progressive ophthalmic lens will have distance, near and intermediate viewing zones correctly aligned with the patient's eye. For example, when the finished eyeglass is worn the fitting cross is typically in front of the patient's pupil. As is apparent, the ophthalmic lens blanks are circular, however, it is understood that the present invention is applicable to blanks of any geometry. Generally, each manufacturer standardizes the patterns and positions of the various verification marks that it employs. Indeed, industry wide standards also exist in that the distance between the center of the two semi-visible marks is 34 mm and each is 17 mm from the geometric center. Commercially available publications provide the specific verification markings used by different manufacturers of progressive lenses. Thus, once the locations of the two semi- visible marks are known, the positions of the verification marks can be readily determined for any particular lens. Suitable ophthalmic lenses are fabricated from materials having superior structural and optical properties. Crystalline quartz, fused silica, soda-lime silicate glass, and plastics such as from polymers based on allyl diglycol carbonate monomers (available as CR-39™ from PPG Industries, Inc., Hartford, CT), diacrylate or dimethacrylate compounds as described in U.S. Patents 5,373,033 and 4,912, 185, both incorporated wherein, and which are available as SPECTRALITE™ from Sola Optical USA, Inc. Petaluma, CA, and polycarbonates such as LEXAN™, available from General Electric Co. , are preferred substrate materials for ophthalmic lenses (including sunglasses). Preferred ophthalmic lenses also include laminated lenses that are fabricated by bonding two lens wafers (i.e., a front wafer and a back wafer) together with a transparent adhesive. Laminated lens wafers are described, for example, in U.S. Patents 5,149,181, 4,857,553, and 4,645,317 and U.K. Patent Application, GB 2,260,937A, all of which are incorporated herein. Suitable substrates further include glass ophthalmic lenses, as described, for instance, in U.S. Patents 3,899,315 and 3,899,314, both of which are incorporated herein. As used herein, the term "ophthalmic lens" or "lens" refers to both single integral body and laminated types and to circular shaped blanks or lens of any geometry. Progressive ophthalmic lenses are typically prepared by casting in a mold. The mold has a shaping surface of the curvature or configuration desired on one side of the finished lens. In addition, the mold has two depressions which correspond to the locations of the reference marks on the progressive ophthalmic lens to be fabricated. The present invention can also be employed to verify that a particular mold is suitable for fabricating the desired progressive ophthalmic lens. This is done by applying verification markings on the mold surface in the same manner as for the ophthalmic lenses and thereafter measuring the mold at these points. The progressive ophthalmic lens can be uncoated or coated for abrasion resistance and/or antireflectivity. Ophthalmic lenses, particularly plastic ones, are coated with a polymeric abrasion or scratch resistance coating that may be about 1 μm to about 12 μm thick. The thickness of the polymeric scratch resistance coating will depend, in part, on the substrate material. Generally, plastic materials such as polycarbonates will require thicker coatings. Ophthalmic lenses may also have an antireflection coating which refers to a substantially transparent multilayer film that is applied to optical systems (e.g., surfaces thereof) to substantially eliminate reflection over a relatively wide portion of the visible spectrum and reduce surface reflectance. The present invention is particularly suited for lenses that have antireflection and/or abrasion resistant coatings and for lenses that are tinted. The reason is that before the coating or tinting process, the initial temporary verification markings on the lenses must be removed. The present invention restores these markings. Figure 2 illustrates a reinker device 30 for restoring verification markings on ophthalmic lenses. The device includes a stage or table 38 which can move on the plane defined by a suitable coordinate system, e.g. , x-y coordinates. In this fashion, the positions on the table are correlated to the coordinate system so that when an ophthalmic lens is placed on the stage the location of any point on the lens surface can be identified. The device includes a magnifying device 32 which can locate the two semi- visible marks on the lens surface. A preferred device is a microscope that preferably has a wire, thread or similar marking in the focus of the eyepiece that functions as a reference line in the field so that the positions of the semi-visible marks can be readily and consistently identified. Preferably, the microscope has a cross hair reticle in the focus of the eyepiece. The microscope is preferably a conventional monocular unit preferably having 20X magnification, a roof prism erector, and a field of view of 3/8 in. (9.5 mm). The 10X eyepiece is preferably replaced with a 10X focusing eyepiece which is designed to receive and focus on a cross hair reticle. The reticle is preferably positioned to coincide with the 2 axes in order to appear aligned. A conventional candelabra base lamp is employed to illuminate the lens. The device further includes a movable pen device 34 having tip 35 for creating markings on lenses. The removable pen device is attached to arm 40. The pen, which preferably has a fine point, is supported or attached to material which has a spring property that will retain the pen during the reinking process yet allows the pen to be removed for recapping, storage and replacement. Arm 40 is fastened to an "L" shaped member which is fastened to a small ball bearing slide. This slide provides precise linear motion in the z-axis. The "L" shaped member can be raised by a thin rod or other conventional means. The reinker device 30 also includes computer which has a database wherein data regarding generic markings or markings for a specific lens type and manufacturer are stored. The particular verifications markings to be generated can be selected by identifying the particular manufacturer and/or lens type from a list provided by the computer, for example, from a generated screen menu. Table 38 is designed to move a lens about a small area (e.g., 6 in. x 3 in.). Movement of the table along the two axes can be achieved by 2 conventional sets of identical hardware that are attached to the underside of the table in a perpendicular arrangement to each other. The particular mechanism for moving the stage is not critical. In a preferred embodiment, two recirculating ball bearing carriages mounted on hardened steel rails provide linear motion of the table. Specifically, the motion of the carriages are controlled by two stepper motors fitted with timing belt pulleys. A timing belt is tensioned between the motor pulley and a larger idler pulley opposite the motor. The belt is anchored to the underside of a moving plate with a double clamp with grooves to receive the teeth of the belt. The belt is cut and one end is clamped in one side of the double clamp anchor. The belt is wrapped around the pulleys with the motor in its most untensioned position and the other end is clamped in the opposite side of the double anchor clamp with small clamp bars. Final tension (2 to 5 lbs.) is achieved by positioning the motor in slotted motor attachment holes. Photodetectors are employed to identify the "home" or end travel position on the surface of the table. For example, to designate the end position along the x- axis, a source of light is employed which directs a beam of light that is perpendicular to the x-axis and that passes through the end of the table in the x-y plane. The light is detected by a photodetector positioned on the opposite side of the rail which is parallel to the x-axis. The carriage which moves on this rail has a small aluminum shield which interrupts the light when the carriage is at the end of travel thereby causing the photodetector to generate a signal for the "home" position relative to the x-axis. A similar mechanism is employed for the y-axis. The stepper motors contain multiple coils which can be energized in a defined pattern to move the rotor in either direction over a wide range of speeds. The computer records the state of coil activation and thereby the position of the rotor, timing belt and carriage. Switching the coil activation results in a discrete step hence the name "stepper motor". In this case, each step of the motor results in a movement of 0.075 mm (0.003 in.). This step size defines the resolution, accuracy and basic coordinate system unit of the machine. A custom printed circuit board (PCB) can be designed and fabricated to control the reinker device. An external connector allows a typical personal computer to be linked to the PCB with a standard printer cable. An additional external connector connects a joystick to the system. The PCB contains circuitry to amplify weak signals from the personal computer to control the motors, lamp and solenoid. Additional circuitry conditions input signals to communicate with the personal computer. In operation, after an ophthalmic lens 36 is placed on table 38 the lens is positioned under the microscope for inspection. A technician directs the computer to move the lens under the microscope so that a semi-visible mark search can be conducted. An input device is employed to interface with the computer and may comprise a keyboard, keypad, mouse, joystick or the like. Employing the microscope, the operator locates the positions of both semi-visible marks and inputs their positions (e.g., x and y coordinates) in the computer. Since the semi- visible marks are typically separated by a known standard distance, i.e., 34 mm, the computer can aid the operator in this task by moving the lens to the approximate location of the second mark, after the first has been located. Once the two semi-visible marks are found relative to the machine coordinate system, the computer can precisely determine the location and orientation of the lens. The pen is used to restore the ink marks precisely in their proper locations. Let (x, y) represent stage rectangular coordinates aligned with the two movement directions on the stage. Let (u, v) represent lens rectangular coordinates where the lens' two logo marks define the u axis (v=0) and point (u=0, v=0) is centered between the two marks. Additionally, define lens polar coordinates given by ρ = sqrt(w 2 + v 2 ) and φ=tan-l(v/w). Upon placement of the lens on the stage, and translation of the lens under the microscope, the location of the logo marks may be identified for the computer. Let (x L , y L ) and (x R , y R ) represent the stage coordinates of left and right marks respectively. The center point between the two logo marks is then given by: X 0 = X h " • ■ \ X R ~ X l) '^ and the angle between the lens u axis and the stage x axis is given by: The transformation of an arbitrary point in (u, v) lens coordinates to (x, y) stage coordinates is then given by: x = x 0 + pcos(φ + θ) = x 0 + sJi ' +y 2 cos tan "1 - + Θ] y = y 0 + psin(φ + θ) = ^ 0 + /w 2 +^ 2 sinltan "1 - + θ An arbitrary arc centered about lens coordinates (u, v) with radius R subtending angles φ, and φ 2 transforms into stage coordinates as centered about (x, y) with R subtending angles φj + θ and φ 2 +θ. Thus, after the transformation between lens and stage coordinates is established, any arbitrary manufacturer verification markings defined with respect to the two logo marks can be transformed into stage coordinates and reproduced on the lens. A program written in C+ + was developed to implement the transformation. The program is set forth in the microfiche appendix. The computer calculates the x-y movements needed to precisely apply the marks for that specific lens location and orientation. The lens is moved from the microscope to a position under the pen mechanism. By repeatedly lowering the pen onto the lens surface and moving the lens under the pen, the image (i.e., verification markings) is reconstructed. Prior to inking a lens, the pen is calibrated to reconcile any error introduced by an abnormal pen or a variation in the mechanism. This can be achieved, for example, by forming an arbitrary point mark with the pen on the lens, aligning the point mark in the cross hairs, and inputting this information which allows the computer to correlate the position of the pen relative to the microscope cross hairs. In the usual case, the technician will be restoring verification marks on progressive ophthalmic lenses from a particular manufacturer or from a particular model lens. If the same manufacturer makes more than one type of progressive ophthalmic lens, each bearing different verification marking patterns; the computer can be programmed to apply the appropriate marks using the coordinate transformation method described above. In this instance, the computer can be instructed to apply appropriate marks using the coordinate transformation methods described above. However, if the technician is working with many types of progressive ophthalmic lenses each with a particular verification marking pattern, the technician then has to identify the particular manufacturer or model and input this information into the computer which selects the proper verification marks to be applied from the computer database. In either event, the technician must identify the particular manufacturer and/or model of the ophthalmic progressive lens so that the computer can generate the proper verification marks. Therefore, when only one manufacturer and/or model progressive ophthalmic lens is involved, the computer database need only contain information regarding the verification marking pattern for that particular manufacturer and/or model. In the preferred embodiment, the verification markings are applied on the surface of the ophthalmic lens by positioning the tip of the pen on the surface of the lens and thereafter moving the table on which the lens is placed. The pen is essentially stationary and moves only in the vertical direction. The movement of the table is computer assisted. However, it is understood that the present invention encompasses a device wherein the verification marks are applied by the computer controlled movement of the pen with the table being stationary or wherein both the pen and table move in a coordinated fashion. The present invention is also employed to produce verification markings on molds that are used to cast progressive ophthalmic lenses. In this case, the mold will be placed on the table of the inventive device and the technician, with the aid of a microscope, will identify the two recesses in the mold surface which correspond to the reference marks on the lens. The same basic procedures can be employed to apply the verification marks on the mold surface. While the invention has been described in terms of various preferred embodiments, the skilled artisan will appreciate the various modifications, substitutions, and changes which may be made without departing from the spirit hereof. The descriptions of the subject matter in this disclosure are illustrative of the invention and are not intended to be construed as limitations upon the scope of the invention. -13a- // // REINKER4.CPP // -4 version - uses REINK4 PCB // Runs the Lens Re-inker hardware // #include < stdlib.h> ^include < stdio.h> #include <dos.h> ^include <conio.h> #include < time.h> #include <math.h> #include < io.h> #include < fcntl.h> #include < iostream.h> #include < fstream.h> #include "reinker4.h" #include "LPT-8255.h" //#include "reinkintf.cpp" #define BURST 1 //#defme DELAY 20 // For 486 system //#defme PenDownDelay 2500 // 486 system //#define PenUpDelay 1000 #defme DELAY 100 // For Pentium 90 system #define PenDownDelay 6500 // Pentium 90 system #defme PenUpDelay 2000 //#define DELAY 200 // For Pentium 133 system //#defme PenDownDelay 10000 // Pentium 133 system //#defme PenUpDelay 4000 //#define DELAY 5 // For 386 system //#defιne PenDownDelay 500 // 386 system //#defme PenUpDelay 200 // Variables are named using Hungarian prefix notation (mostly) -13b- // i= integer, c=char, d= double // Global Variables extern const unsigned char cSequence[] ; // const array defined in reinker.h // 8 element stepping sequence repeated 32 times unsigned char cgXCurrent = 0, // keeps track of current position in the cgYCurrent = 0; // stepping sequence for x & y, wraps at 255 & 0 int igX = 0, igY = 0; // current X & Y location of stage int igXcal = XLLOGOPEN-XLLOGOVIEW, igYcal = YLLOGOPEN- YLLOGOVIEW; //pen-to-view steps int igPenDown = 0; // 1 = pen is down int igXt = XLLOGOPEN - 223, igYt = YLLOGOPEN; // Transform parameters to Lens coordinate system double dgThetat =0; // x, y, theta int igSide = 0, igModel = 0, igMfg = 0, igStatus = 0; // Current user param' s const double PI = 3.141592654; main() { int done, key, i, currentChoice; int iMoveCount = 0;// Counts # of joystick moves in a row for speed-up unsigned char clnByte; init8255(); paintScreenO; readIniData(); find(); 7 move to sensors home position moveto(XLOAD, YLOAD); // move to load position gotoxy(24, 16); cprintf("Ready "); gotoxy(l, 1); // Main program loop - has two major sections: // 1) checks for keypress, if pressed does processing for 'key' // 2) checks joystick buttons, does movement & starts button actions currentChoice = 0; -13c- done = 0; // Flag for loop exit while(ldone) { if(kbhit()) { // Has a key been pressed? key = getch(); // Yes, perform specific key functions if (key = = 0) { key = getch(); switch (key) { case 0x4D: // Right Arrow movex(BURST); break; case 0x4B: // Left Arrow movex(-BURST); break; case 0x48: // Up Arrow currentChoice--; if (currentChoice < 0) currentChoice = 7; display Menu(currentChoice) ; break; case 0x50: // Down Arrow currentChoice+ +; if (currentChoice > 7) currentChoice = 0; display Menu(currentChoice) ; break; } } else { switch (key) { // case OxlB: // Escape key // done = 1 ; // break; case OxOD: // Return key fflush(stdin); switch (currentChoice) { case O: reink(); break; case 1: verify(); break;// Verify markings case 2: changeSide(); break;// Change Side case 3: changeModel(); break;// Change Lens Type case 4: changeMfgO; break; // Change Manufacturer case 5: calibrate(); break; case 6: display _help(); break; // Help case 7: done = 1; break; // Quit } window(l, 1,80,25); -13d- textbackground(BLUE) ; textcolor( WHITE); gotoxy(24, 16); cprintf("Ready "); display Menu(currentChoice) ; break; case 'H': case 'h': case 0x3F: // '? * key display _help(); break; case 'B': // 'b' key, brand select case 'b': changeMfgO; break; case 'C: case 'c': // 'c' key, calibrate calibrateO; break; case 'L' : // T key, Lens Model select case T: changeModelO; break; case 'M': case 'm': // 'm' key, go ink reink(); break; case 'Q': // 'q' key, Quit case 'q': done = 1; break; case 'S': // V key case 's': changeSideO; break; case 'V: // V key for verify case V: verify 0; break; default: //printf(" %X ", key); break; } -13e- } } // Check joystick port for actions to perform clnByte = in(PORTB); if(-(dnByte | ANYMOVE)) { iMoveCount + + ; // Count # of moves in a row if( " (dnByte | RIGHT)) {cgXCurrent+ + ; igX+ + ;} if(-(cInByte j LEFT)) {cgXCurrent-; igX--;} if(-(dnByte j UP)) {cgYCurrent+ + ; igY+ + ;} // currentChoice--; // if (currentChoice < 0) currentChoice = 7; // display Menu(currentChoice); 7} iff (clnByte | DOWN)) {cgYCurrent-; igY-;} // currentChoice + + ; // if (currentChoice > 7) currentChoice = 0; // display Menu(currentChoice); 7} // Check to keep stage in bounds if (igX < 8) {igX+ + ; cgXCurrent + + ;} if (igX > XMAX - 40) {igX-; cgXCurrent-;} if (igY < 40) {igY+ + ; cgYCurrent+ + ;} if (igY > YMAX - 40) {igY-; cgYCurrent-;} out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); shortdelay (DELAY); if(-(dnByte | BUTTON1)) iMoveCount = 0; // Next statement shortens delay for longer moves else for (i = (50 - iMoveCount); i > 0; i-) shortdelay (DELAY); } else iMoveCount = 0; if ( " (clnByte | BUTTON1)) { switch (currentChoice) { case 0: reink(); break; case 1: verify(); break;// Verify markings case 2: changeSide(); break;// Change Side case 3: changeModel(); break;// Change Lens Type case 4: changeMfgO; break; // Change Manufacturer case 5: calibrate(); break; case 6: display _help(); break; // Help case 7: done = 1; break; // Quit ■ 13f- } for (i = 50; i > 0; i-) shortdelay(DELAY); } */ } // End of main program loop out(PORTA, 0); // Turn off all output bits out(PORTC, 0); return(O); // End of main() } // reink() - perform re-inking sequence void reink(void) { int iCommand, xleft, yleft; int deltaX, deltaY; Mark mTemp[20]; // moveto(XLOAD, YLOAD); // iCommand = iUserMove(); gotoxy(24, 16); cprintfC'Marking "); moveto(XLLOGOVIEW, YLLOGOVIEW); iCommand = iUserMove(); if (iCommand = = -1) { // If escape has been pressed, move home & return moveto(XLOAD, YLOAD); return; } xleft = igX; yleft = igY; moveto(XLLOGOVIEW - 450, YLLOGOVIEW); iCommand = iUserMove(); if (iCommand = = -1) { // If escape has been pressed, move home & return moveto(XLOAD, YLOAD); return; } deltaX = xleft - igX; deltaY = yleft - igY; igXt = igX + deltaX/2 + igXcal; igYt = igY + deltaY/2 + igYcal; -13g- dgThetat = atan((double)deltaY / (double)deltaX); // cprintf("Xt = %d, Yt = %d, Thetat = %f\n\r", igXt, igYt, dgThetat); switch (igModel) { case O: if (igSide = = 1) mm2steps(mVIPL, mTemp); else mm2steps(mVIPR, mTemp); break; case 1: case 2: if (igSide = = 1) mm2steps(mXLL, mTemp); else mm2steps(mXLR, mTemp); break; case 3: if (igSide = = 1) mm2steps(mXLGoldL, mTemp); else mm2steps(mXLGoldR, mTemp); break; case 4: if (igSide = = 1) mm2steps(mGeneric2L, mTemp); else mm2steps(mGeneric2R, mTemp); break; case 5: if (igSide = = 1) mm2steps(mGeneric4L, mTemp); else mm2steps(mGeneric4R, mTemp); break; case 6: if (igSide = = 1) mm2steps(mPerceptaL, mTemp); else mm2steps(mPerceptaR, mTemp); break; case 7: rnm2steps(mAccess, mTemp); -13h- break; case 8: mm2steps(mCircleLogos, mTemp); break; case 9: if (igSide = = 1) mm2steps(mDotL, mTemp); else mm2steps(mDotR, mTemp); break; case 10: mm2steps(mDotLogos, mTemp); break; case 11: mm2steps(mHappy, mTemp); } draw(mTemp); // draw(mBasicInk); // moveto(XLLOGOVIEW, YLLOGOVIEW); /* transform(223, 0, &xleft, &yleft); moveto(xleft - igXcal, yleft - igYcal); // Left logo iCommand = iUserMove(); transform(-223, 0, &xleft, &yleft); moveto(xleft - igXcal, yleft - igYcal); // Right logo // moveto(XLLOGOVIEW - 450, YLLOGOVIEW); iCommand = iUserMove(); */ moveto(XLOAD, YLOAD); return; } /**************************************************************** // verifyO - verify ink marks / logos //**************************************************************** void verify(void) { int iCommand, xleft, yleft; gotoxy(24, 16); cprintf("Verifying"); transform(223, 0, &xleft, &yleft); moveto(xleft - igXcal, yleft - igYcal); // Left logo -13i- iCommand = iUserMove(); if (iCommand = = -1) { // If escape has been pressed, move home & return moveto(XLOAD, YLOAD); return; } transform(-223, 0, &xleft, &yleft); moveto(xleft - igXcal, yleft - igYcal); // Right logo // moveto(XLLOGOVIEW - 450, YLLOGOVIEW); iCommand = iUserMove(); moveto(XLOAD, YLOAD); return; } // movex(n) - raw move routine, moves n steps in x or -x direction void movex(int n) { int i; if (n > 0) { for(i = 0; i <n; i+ +) { cgXCurrent + +; igX+ + ; // Check to keep stage in bounds if (igX > XMAX - 40) {igX-; cgXCurrent-;} out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); shortdelay (DELAY); } } if (n < 0) { for(i = 0; i < -n; i+ +) { cgXCurrent-; igX~; // Check to keep stage in bounds if (igX < 8) {igX+ + ; cgXCurrent+ + ;} out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); shortdelay (DELAY); } } -13j- //outportb(BASE+ l, 0); return; } // movey(n) - raw move routine, moves n steps in y or -y direction void movey(int n) { int i; if (n > 0) { // Move in positive direction? for(i = 0; i <n; i+ +) { out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); cgYCurrent+ + ; igY+ +; shortdelay (DELAY); } } if (n < 0) { for(i = 0; i< -n; i+ +) { out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); cgYCurrent--; igY-; shortdelay (DELAY); } } //outportb(BASE, 0); return; } // moveto(x, y) - straight line move from current position to x, y void moveto(int xl, int yl) { int xO, yO, xNext, yNext, deltaX, deltaY, steps, i; float slopeX, slopeY; xO = igX; // xO, yO is where we started from yO = igY; deltaX = xl - xO; // calc the # of steps in each direction deltaY = yl - yO; -13k- // set steps = max number of steps (x or y) disregarding sign steps = (abs(deltaX) > abs(deltaY)) ? abs(deltaX) : abs(deltaY); if( steps = = 0) return; // already at destination, just return // calc slope factors, slope = 1 for long direction (or -1) // slope is between 0 and 1 (or -1) for short direction slopeX = (float)deltaX / (float)steps; slopeY = (float)deltaY / (float)steps; for (i = 1; i < = steps; i + +) { xNext = xO + (int)((float)i * slopeX); yNext = yO + (int)((float)i * slopeY); switch (xNext - igX) { case -1: igX--; cgXCurrent-; break; case 1: igX+ + ; cgXCurrent+ + ; break; } switch (yNext - igY) { case -1: igY--; cgYCurrent-; break; case 1 : igY+ + ; cgYCurrent-f- + ; break; } // Check to keep stage in bounds if (igX < 8) {igX+ + ; cgXCurrent+ + ;} if (igX > XMAX - 40) {igX~; cgXCurrent-;} if (igY < 40) {igY+ + ; cgYCurrent+ + ;} if (igY > YMAX - 40) {igY-; cgYCurrent-; } out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); shortdelay(DELAY); } return; } -131- // arc(x,y,r,thetaO, thetal) - draw an arc // x,y is the center of the arc // r is the radius of the arc (in steps) // thetaO is the starting angle (in degrees) // measured CCW from positive X axis // thetal is the ending angle of the arc void arc(int xl, int yl, int r, int thetaO, int thetal) { int xO, yO, xNext, yNext, deltaTheta, steps, i; double dThetaO, dThetal, dr, slope; out(PORTC, 0); // Pen up dThetaO = PI * (double)thetaθ / 180; dThetal = PI * (double)thetal / 180; dr = (double) r; xO = xl + (int)(dr * cos(dThetaO)); yO = yl + (int)(dr * sin(dThetaO)); moveto(xO, yO); out(PORTC, 1); // Pen down shortdelay (PenDownDelay) ; igX = xO; igY = yO; deltaTheta = thetal - thetaO; steps = (20 * r); // * deltaTheta) / 360; slope = (dThetal - dThetaO) / (double)steps; for (i = 1; i < = steps; i+ +) { xNext = xl + (int)(dr * cos(dThetaO + (float)i * slope)); yNext = yl + (int)(dr * sin(dThetaO + (float)i * slope)); if ((xNext - igX) < 0) { igX-; cgXCurrent--; } else if ((xNext - igX) > 0) { igX+ + ; cgXCurrent+ + ; } if((yNext - igY) < 0) { igY--; cgYCurrent--; } else if((yNext - igY) > 0) { igY+ + ; -13m- cgYCurrent+ + ; } // Check to keep stage in bounds if (igX < 8) {igX+ + ; cgXCurrent + + ;} if (igX > XMAX - 40) {igX~; cgXCurrent-; } - if (igY < 40) {igY+ + ; cgYCurrent+ + ; } if (igY > YMAX - 40) {igY-; cgYCurrent-;} out(PORTA, cSequence[cgXCurrent] | (cSequence[cgYCurrent] < < 4)); shortdelay(DELAY); } if(!igPenDown) { out(PORTC, 0); // Restore pen to previous position shortdelay (PenUpDelay) ; } return; } II shortdelay - void shortdelay(int n) { long int i, j, k; for(i = 0; i < n; i+ +) { k = 0; for(j = 0; j < 1000; j + +) k = k + 2; } return; } // test_cycle - void test_cycle(void) { int key; while(!kbhit()) { moveto(654 , 530) ; // Left Logo moveto(208,530); // Right Logo cross(1687, 482, 20, 20); cross(1240, 482, 20, 20); } -1311- key = getch(); return; } // calibrate - void calibrate(void) { int iCommand; char buffer[1000]; gotoxy(24, 16); cprintf(" Calibrating"); gettext(3, 18, 41 , 23, buffer); window( 3, 18, 41, 23); textbackground(WHITE) ; textcolor(BLACK); clrscr(); moveto(XLLOGOPEN, YLLOGOPEN); penDown(); shortdelay (PenDownDelay * 3); penUp(); shortdelay (PenUpDelay) ; // moveto(XLLOGOVIEW, YLLOGOVIEW); moveto(XLLOGOPEN - igXcal, YLLOGOPEN - igYcal); cprintf(" Position the dot in the crosshairs. \n\r"); cprintf(" Press the trigger when ready. \n\r"); iCommand = iUserMove(); if (iCommand = = 1 | | iCommand = = 2) { // cprintfC'Xcal = %d Ycal = %d ", igXcal, igYcal); igXcal = XLLOGOPEN - igX; igYcal = YLLOGOPEN - igY; // cprintfC'Xcal = %d Ycal = %d ", igXcal, igYcal); ofstream ReinkIniOut( " Reink. ini " ) ; ReinklniOut < < igXcal < < endl < < igYcal < < endl; ReinklniOut.closeO; cprintf("\n\r Calibration complete. \n\r"); } else cprintf(" Calibration aborted.\n\r"); moveto(XLOAD, YLOAD); -13o- puttext(3, 18, 41, 23, buffer); retorn; } // iUserMove - allows user to move x-y table & returns terminating // button or keyboard command int iUserMove(void) { int done, iMoveCount, iDelayCount, i; unsigned char key, clnByte; done = 0; while(ldone) { if(kbhit()) { // Has a key been pressed? key = getch(); // Yes, perform specific key functions switch (key) { case OxlB: // Escape key done = -1; break; case OxOD: // Enter key done = 1; break; case 0x4D: // Right Arrow movex(BURST); break; case 0x4B: // Left Arrow movex(-BURST); break; case 0x48: // Up Arrow movey(BURST); break; case 0x50: // Down Arrow movey(-BURST); break; case 'B': // 'b' key, brand select case 'b': changeMfgO; break; case 'L': II 'V key, Lens Model select case T: changeModelO; break; case 's': // 'S * key -Op- case 'S': changeS ide(); break; default: done = 1 ; } } // Check joystick port for actions to perform clnByte = in(PORTB); iff (clnByte | RIGHT)) {cgXCurrent+ + ; igX+ + ;} iff (clnByte j LEFT)) {cgXCurrent-; igX-;} iff (clnByte | UP)) {cgYCurrent+ + ; igY+ + ;} if( ~ (cInByte j DOWN)) {cgYCurrent-; igY-; } if ( " (clnByte j ANYMOVE)) iMoveCount + + ; // Count # of moves in a row else iMoveCount = 0; // Check to keep stage in bounds if (igX < 8) {igX+ + ; cgXCurrent+ + ;} if (igX > XMAX - 40) {igX-; cgXCurrent-; } if (igY < 40) {igY+ + ; cgYCurrent+ + ;} if (igY > YMAX - 40) {igY-; cgYCurrent-; } out(PORTA, cSequence[cgXCurrent] | (cSequencefcgYCurrent] < < 4)); shortdelay(DELAY); //if( " (clnByte | BUTTONl)) iMoveCount = 0; // Trigger button speed-up // Next statement shortens delay for longer moves // else if (iMoveCount < 10) iDelayCount = 50; else if (iMoveCount < 20) iDelayCount = 25; else iDelayCount = 12; for (i = iDelayCount; i > 0; i~) shortdelay (DELAY); if( " (cInByte | BUTTONl)) done = 2; if( " (cInByte j BUTTON2)) done = 3; } return(done); } * void line(int xO, int yO, int xl, int yl) { -13q- movetoLC(xO, yO); penDown(); shortdelay(PenDownDelay) ; movetoLC(xl, yl); penUp(); shortdelay(PenUpDelay) ; return; } * void dot(int xO, int yO) { movetoLC(xO, yO); penDown(); shortdelay(PenDownDelay * 3); // shortdelay (PenDownDelay); penUp(); shortdelay (PenUpDelay) ; return; } * logo - draw a SOLA logo centered at x, y void logo(int x, int y) { const int radius = 22; // radius should be 13 half steps = 2 mm penDown(); // this keeps the pen down for the crossbar arcLC(x, y, radius, 35, 180); // penDown(); movetoLC(x + radius, y); arcLC(x, y, radius, 360, 215); penUp(); shortdelay (PenUpDelay) ; return; } * trefoil - draw a trefoil centered at x, y void trefoil(int x, int y) { const int radius = 20; // radius should be 13 half steps = 2 mm penDown(); // this keeps the pen down for the crossbar -13r- arcLC( 0, 10, radius, 170, 370); arcLC( 9, -5, radius, 247, 57); arcLC( -9, -5, radius, 483, 293); arcLC(x, y, radius, 35, 180); // penDown(); movetoLC(x + radius, y); arcLC(x, y, radius, 360, 215); penUp(); shortdelay(PenUpDelay) ; return; }*/ * void cross(int x, int y, int height, int width) { line(x + width/2, y, x - width/2, y); shortdelay(PenUpDelay) ; line(x, y + height/2, x, y - height/2); return; } * Transform point to Lens Coordinate system * Uses the global transform variables Xt, Yt, and Thetat void transform(int xO, int yO, int* xl, int* yl) { double rO, thetaO; rO = sqrt((double)xO * (double)xO + (double)yθ * (double)yθ); // rO = sqrt(xO*xO + yO*yO); if (xO = = 0) { if (yO > = 0) thetaO = PI / 2; else thetaO = 3 * PI / 2; } else thetaO = atan((double)yO / (double)xθ); if ( xO < 0 ) thetaO = PI + thetaO; *xl = igXt + (int)(rO * cos(thetaO + dgThetat)); *yl = igYt + (int)(rO * sin(thetaO + dgThetat)); // printf("xO = %d, yO = %d, xl = %d, yl = %d\n\r", xO, yO, *xl, *yl); -13s- return; } * void angletransform(int thetaO, int* thetal) { int iThetat; iThetat = (int) (180 * dgThetat / PI); *thetal = thetaO + iThetat; retorn; } * void movetoLC(int xl, int yl) { int x2, y2; transform(xl, yl, &x2, &y2); moveto(x2, y2); retarn; } * void arcLC(int xl, int yl, int r, int thetaO, int thetal) { int xnew, ynew, thetaOnew, thetalnew; transform(xl, yl, &xnew, &ynew); angletransform(thetaO, &thetaOnew); angletransform(thetal, &thetalnew); arc(xnew, ynew, r, thetaOnew, thetalnew); return; } * findO - find absolute position using x & y opto sensors void fιnd(void) { igX = 0; // Set coord's to worst case, upper left corner igY = YMAX; while((in(PORTB) & XHOME) && (igX ! = XMAX)) movex(l); while((in(PORTB) & YHOME) && igY) movey(-l); -13t- if (igX ! = XMAX) igX = XSENSOR; // If not XMAX it must be at sensor if (igY ! = 0) igY = YSENSOR; // If not zero it must be at sensor moveto(XSENSOR - 400, YSENSOR + 400); // Move to sensor + 200 & while((in(PORTB) & XHOME) && igX) movex(l); // re-approach while((in(PORTB) & YHOME) && igY) movey(-l); if ((igX = = XMAX) I I (igY = = 0)) printf(" Sensors not found.\n\r"); else { igX = XSENSOR; igY = YSENSOR; } return; } * void draw(Mark *markarray) { int i, key; // Mark *nextmark; // union Markptr markptru; movetoLC(-400, 0); // This gives the user a chance to abort before 1st mark for (i = 0; markarray[i].type ! = 0; i+ +) { while (kbhit()) { // Check for Abort command (Esc key) key = getch(); // Get key value //cprintfC 1 st: % d\n\r" , key) ; if (key = = 0) key = getch(); // get 2nd char if comand //cprintf("2nd: %d\n\n\r", key); if (key = = OxlB) return; // Escape key, bail out } // printf("This is draw() pass %d\n\r", i); switch (markarray[i].type) { case DOT: dot(markarray[i] .xstart, markarray[i] .ystart); break; case LINE: line(markarray[i]. xstart, markarray[i]. ystart, markarr ay [i] . xend , markarray [i] . y end) ; break; case ARC: arcLC(markarray[i] .xstart, markarray[i] .ystart, markarray [i] . xend, markarray[i] .yend, -13u- markarray [i] . theta) ; break; case CROSS: cross(markarray [i] . xstart, markarray [i] .ystart, markarray [i] . xend , markarray [i] . y end) ; break; case LOGO: logo(markarray[i]. xstart, markarray[i]. ystart); break; // What follows is the recursive case which will be left for another day /* case MARK: // How do you pass a pointer with 2 integers? markptru = &markarray[i] ; nextmark = markptru. markpointer; draw(nextmark); break; */ } } return; } void mm2steps(Mark* mmMark, Mark* stepMark) { int i; for (i = 0; mmMark[i].type ! = 0; i + +) { stepMark[i].type = mmMark[i].type; stepMark[i]. xstart = -(int) ((float)mmMark[i]. xstart * 1.3138 + .499); stepMark[i]. ystart = -(int) ((float)mmMark[i] . ystart * 1.3138 + .499); switch (mmMark[i]. type) { case DOT: stepMark[i].xend = 0; stepMark[i].yend = 0; stepMark[i]. theta = 0; break; case LINE: stepMark[i].xend = -(int) ((float)mmMark[i].xend * 1.3138 + .499); stepMark[i].yend = -(int) ((float)mmMark[i].yend * 1.3138 + .499); stepMark[i]. theta = 0; break; case ARC: stepMark[i].xend = (int) ((float)mmMark[i].xend * 1.3138 + .499); stepMark[i].yend = mmMark[i].yend; stepMark[i]. theta = mmMark[i]. theta; -13v- break; case CROSS: stepMark[i].xend = (int) ((float)mmMark[i].xend * 1.3138 + .499); stepMark[i].yend = (int) ((float)mmMark[i].yend * 1.3138 + .499); stepMark[i]. theta = 0; break; case LOGO: stepMark[i].xend = (int) ((float)mmMark[i].xend * 1.3138 + .499); stepMark[i].yend = 0; stepMark[i]. theta = 0; break; } } stepMark[i].type = 0; return; } * readlniData - void readIniData(void) { ifstream infιle("Reink.ini"); if (infile && !infιle.eof()) { infile > > igXcal; infile > > igYcal; infile. close(); } return; } -13w- #include <conio.h> #defιne Version "4.0" extern int igSide, igModel, igMfg, igStatus; // Current user param' s int paintScreen(void) { void display Menu(int); int i; textmode(C80); /* Put screen in 80 col. color mode */ textbackground(B LUE) ; textcolor(WHITE); clrscrO; gotoxy(80,25); /* Write lower right hand corner border */ putch(188); /* first to prevent screen scrolling */ gotoxy(l,l); putch(201); /* Write upper left hand corner border */ for(i = l; i < =78; i+ +) putch(205) ; /* Write border across top */ putch(187); /* Write upper right corner border */ putch(186); gotoxy(80,2); for(i=2; i < =23; i+ +) { gotoxy(80,i); putch(186); /* This writes right hand border */ putch(186); /* This wraps around to write left border */ } gotoxy(l,24); putch(200); /* Write lower left corner of border */ for(i = l; i < =78; i+ +) putch(205); /* Write bottom of border */ /* Lower right corner has already been written */ /* Create Title Block, window w/ shadow */ window(22,3,59,6); textbackground(BLACK) ; clrscr(); window(21, 2,57,5); textbackground(LIGHTGRA Y) ; textcolor(WHITE); clrscr(); gotoxy(l,2); cprintfC SOLA Optical USA Reinker\n\r"); cprintfC s Ver. %s ",_DATE_, Version); display Menu(0); textbackground(B LUE) ; -13x- textcolor(WHITE); gotoxy(53, 8); cprintfC'ACTION"); gotoxy(10, 10); // highvideoO; cprintf("S"); // lowvideo(); cprintf("ide: Right"); gotoxy(10, 12); // cprintfC'Lens Model: VIP"); gotoxy(10, 14); cprintfC'Brand: SOLA Optical"); gotoxy(10, 16); cprintf(" Status: Power-Up"); // textbackground( WHITE); // textcolor(BLACK); // gotoxy(57,23); // cprintfC File: CLOSED "); // gotoxy(57, 24); // cprintfC Printer: OFF "); // window(4,9,50,22); // clrscr(); return 0; } void displayMenu(int choice) { int i; /* Create action menu */ char *menu[] = { "Mark Lens "Verify Lens Marking " , "Side Select "Lens Model Select "Brand Select "Calibrate "Help "Quit }; // window(54, 11,77,22); window(44,9,67,20); textbackground(CYAN) ; textcolor( WHITE); clrscrO; -13y- cprintf("\n\r"); for(i=0; i < =7; i+ +) { if(i= = choice) textbackground(LIGHTGRAY); else textbackground(CYAN); textcolor( YELLOW); cprintfC %c", *menu[i]); textcolor( WHITE); cprintf( " % s " , menu[i] + 1 ) ; } window( 1,1, 80,25); textbackground(WHITE) ; textcolor(BLACK); return; } // display_help - void display_help(void) { char buffer[1000]; gettext(3, 18, 41, 23, buffer); window( 3, 18, 41, 23); textbackground(WHITE) ; textcolor(BLACK); clrscrO; cprintf("\n\r"); cprintf(" Highlight a Menu choice and Press \n\r"); cprintf(" < Enter > , or\n\r"); cprintf(" Press the first letter of the\n\r Menu choice. \n\r"); cprintf(" < Esc > will cancel & return to the Menu. "); // cprintfC 'a' - 'ARC draw an arc(s)\n\r"); // cprintf(" 'C - 'CALIBRATE' calibrate stage positioning\n\r"); // cprintfC 'd' - 'DISPLAY' display current coordinates"); hile(!kbhit()); getchO; puttext(3, 18, 41, 23, buffer); return; } // changeSide - -13z- void changeSide(void) { igSide+ + ; if (igSide > 1) igSide = 0; window( 1,1, 80,25); textbackground(BLUE) ; textcolor(WHITE); gotoxy(24, 10); switch (igSide) { case 0: cprintf(" Right"); break; case 1: cprintf("Left "); //break; //case 2: cprintf("None "); } gotoxy(l ,l); remrn; } / **************************************************************** // changeModel - / **************************************************************** void changeModel(void) { igModel+ + ; if (igModel > 11) igModel = 0; window( 1,1, 80,25); textbackground(BLUE) ; textcolor(WHITE); gotoxy(24, 12); switch (igModel) { case O cprintfC'VIP break case 1 cprintf("XL break case 2 cprintfC'VIPGold break case 3 cprintf("XL Gold break case 4 cprinft(" Generic 2 break case 5 cprintf(" Generic 4 break case 6 cprintf("Percepta break case 7 cprintf("Access break case 8 cprintf("Circle Logos break case 9 cprintf("Dot Near/Far break case 10: cprintf("Dot Logos "); break; case 11 : cprintf("Happy Face "); break; gotoxy(l,l); return; -13aa- } **************************************************************** // changeMfg - void changeMfg(void) { igMfg + + ; if (igMfg > 1) igMfg = 0; window( 1,1, 80,25); textbackground(BLUE) ; textcolor(WHITE); gotoxy(24, 14); switch (igMfg) { case 0: cprintf("Sola Optical"); break; case 1 : cprintf(" Generic "); } gotoxy(l,l); return; } -13bb- //********************************************************* // // REINKER.H by Tom Hawkins 12/30/96 // Header file for REINKER. CPP // #ifndef _REINKER4_H // Sentry to include only once #define _REINKER4_H struct Mark { int type; int xstart; int ystart; int xend; int yend; int theta; }; void display _help(void); void test_cycle(void); void calibrate(void); void shortdelay (long int); void movex(int); void movey(int); void moveto(int, int); void movetoLCønt, int); // Move-to, Lens Coordinate system void arc(int, int, int, int, int); void arcLCønt, int, int, int, int); // Draw arc, Lens Coordinate system void line(int, int, int, int); void cross(int, int, int, int); void logo(int, int); void dot(int, int); void find(void); int iUserMove(void); void reink(void); void draw(Mark*); void mm2steps(Mark*, Mark*); void transformønt, int, int*, int*); int paintScreen(void); void displayMenu(int); void verify(void); void changeSide(void); void changeModel(void); -Dec- void changeMfg(void); void readIniData(void); #define VERSION3 #define BASE 0x390 // Base address of CIO-DO48DD output board // was 0x300 // Port A @ BASE Y stepper, bits 0-3 // Port A @ BASE X stepper, bits 4-7 // Port C @ BASE +2 pen up/down at bit 0 // Port B @ BASE + 1 // 8255 Control port @ BASE +4, init to 0x8A #define PPORT BASE+ 1 // Input Port Base Address, 8255 Port B #define RIGHT OxDF // Mask for Right button (joystick), Bit 5, Pin #defιne LEFT OxEF // Mask for Left button (joystick), Bit 4, Pin #define UP 0xF7 // Mask for Up button (joystick), Bit 3, Pin #define DOWN OxFB // Mask for Down button (joystick), Bit 2, Pin #defιne ANYMOVE 0xC3 // Mask for any move button pressed (joystick), Bits 2-5 #define BUTTONl OxBF // Mask for joystick buttonl (left and trigger), Bit 6, Pin #defιne BUTTON2 OxFE // Mask for joystick button2 (right & top stick button), Bit 7, Pin #define XHOME 0x01 // Mask for X sensor input, Bit 0, DB-37 pin x #define YHOME 0x02 // Mask for Y sensor input, Bit 1, DB-37 pin y // All of the following locations are referenced to 0,0 at full lower left // 5/4/97 Adding 40 steps to all X values to move X=0 left 1/8" #define XSENSOR 1800 // Location of X sensor (approached from +X) #define YSENSOR 126 // Location of Y sensor (approached from + Y) #define XMAX 1840 // X mechanical stop #defme YMAX 1170 // Y mechanical stop #defme XLLOGOVIEW 540 // Location to put Left logo in view #define YLLOGOVIEW 435 #defme XLLOGOPEN 1542 // Location to put Left logo under pen #define YLLOGOPEN 444 #defιne XLOAD 1800 // Location of lens load/unload #define YLOAD 110 #defιne STEPSPERMM 13 // Number of half steps per millimeter #defιne XLEFT2RIGHT 34*STEPSPERMM // # of steps from left to right logos // Macros to in-line pen functions: #define penDownQ out(PORTC, l);igPenDown = 1 -13dd- #defme penUpO out(PORTC, 0);igPenDown = 0 // Bit 0 - A // Bit 1 - !A // Bit 2 - B // Bit 3 - !B //unsigned char cSequence[4] = {0x5, 0x9, OxA, 0x6}; const unsigned char cSequence[256] = {0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl, 0x9, 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl 0x9 0x8, OxA, 0x2, 0x6, 0x4, 0x5, Oxl}; struct IniFileData { int currentX; int current Y; -13ee- int Xcal; int Ycal; int Side; int Model; int Mfg; int rightholeL; int leftholeY; }; struct Markmm { int type; float xstart; float ystart; float xend; float end; float theta; }; //union Markptr { // int type; // Mark *markpointer; // }; **** * Mark types * 0 - list terminator * 1 - dot dot(x, y); * 2 - line line(xl, yl, x2, y2); * 3 - arc arc(x0, yO, r, thetaO, thetal); * 4 - cross cross(x, y, height, width, [theta]) * 5 - logo logo(x, y, [size]); * 6 - character drawchar(x, y, char, size, theta); * 7 - mark array (pointer) * 8 - polygon (?) not really needed * 9 - bar code, dotted line, dashed line, filled polygon, filled circle, * bit map image(?), * ***/ #define DOT 1 #defme LINE 2 ■13ff- #define ARC 3 #define CROSS 4 #define LOGO 5 #define CHAR 6 #define MARK 7 Mark mBasicInk[] = { {DOT, 0, 0, 0, 0, 0}, {LINE, 400, 0, 300, 0, 0}, {LOGO, 227, 0, 0, 0, 0}, {LINE, 150, 0, 50, 0, 0}, {LINE, -50, 0, -150, 0, 0}, {LOGO, -227, 0, 0, 0, 0}, {LINE, -300, 0, -400, 0, 0}, {CROSS, 0, -27, 30, 100, 0}, {ARC, 0, -100, 83, 135, 405}, {ARC, 40, 200, 50, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mVIPL[] = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, -25, -140, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mVIPR[] = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, -13gg- {ARC, 0, 80, 60, 135, 405}, {ARC, 25, -140, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mXLL[] = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, -25, -150, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mXLR[] = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, 25, -150, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mXLGoldL[] = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, ■13hh- {ARC, -25, -170, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mXLGoldR[] = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, 25, -170, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mPerceptaLQ = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {ARC, 170, 10, 20, 170, 370}, {ARC, 179, -5, 20, 247, 57}, {ARC, 161, -5, 20, 483, 293}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, -25, -170, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mPerceptaR[] = { {LINE, -260, 0, -210, 0, 0}, {ARC, -170, 10, 20, 170, 370}, {ARC, -161, -5, 20, 247, 57}, {ARC, -179, -5, 20, 483, 293}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, -13ϋ- {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, 25, -170, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mAccessQ = { {LINE, -260, 0, -210, 0, 0}, {LOGO, -170, 0, 0, 0, 0}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {LOGO, 170, 0, 0, 0, 0}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, -250, 200, 220, 320}, {0, 0, 0, 0, 0, 0} }; Mark mGeneric2L[] = { {LINE, -260, 0, -210, 0, 0}, {ARC, -170, 0, 20, 0, 360}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {ARC, 170, 0, 20, 0, 360}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, -25, -150, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mGeneric2R[] = { {LINE, -260, 0, -210, 0, 0}, {ARC, -170, 0, 20, 0, 360}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {ARC, 170, 0, 20, 0, 360}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 20, 10, 50, 0}, -13jj- {ARC, 0, 80, 60, 135, 405}, {ARC, 25, -150, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mGeneric4LD = { {LINE, -260, 0, -210, 0, 0}, {ARC, -170, 0, 20, 0, 360}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {ARC, 170, 0, 20, 0, 360}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 40, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, -25, -150, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mGeneric4R[] = { {LINE, -260, 0, -210, 0, 0}, {ARC, -170, 0, 20, 0, 360}, {LINE, -130, 0, -80, 0, 0}, {DOT, 0, 0, 0, 0, 0}, {LINE, 80, 0, 130, 0, 0}, {ARC, 170, 0, 20, 0, 360}, {LINE, 210, 0, 260, 0, 0}, {CROSS, 0, 40, 10, 50, 0}, {ARC, 0, 80, 60, 135, 405}, {ARC, 25, -150, 36, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mHappyG = { {ARC, 0, 0, 280, 20, 160}, {ARC, -120, 130, 15, 0, 360}, {ARC, 120, 130, 15, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mDotL[] = { {DOT, 0, 0, 0, 0, 0}, {DOT, 0, 80, 0, 0, 0}, -13kk- {DOT, -30, -150, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }; Mark mDotR[] = { {DOT, 0, 0, 0, 0, 0}, {DOT, 0, 80, 0, 0, 0}, {DOT, 30, -150, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }; Mark mCircleLogos[] = { {ARC, -238, 0, 30, 0, 360}, {CROSS, 0, 0, 20, 20, 0}, {ARC, 238, 0, 30, 0, 360}, {0, 0, 0, 0, 0, 0} }; Mark mDotLogos[] = { {DOT, -238, 0, 0, 0, 0}, {DOT, 238, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }; #endif // End of Sentry ifndef -1311- LPT-8255.cpp Parallel printer port to 8255 I/O Functions Created 4/29/97 by Tom Hawkins //#include < stdio.h> //#include < conio.h> ^include <dos.h> #include "lpt-8255.h" void init8255(void) { // outportb(BASE+3, 0x8A); // Init 8255 A, CL out, B, CH in outportb(LPTECR, 0x20); // Set ECP to PS/2 mode outportb(LPTCONTROL, 0x07); out(PORTA, 0); out(PORTC, 0); out(PORTCNTL, 0x8A); return; } void out(int iPortNum, unsigned char uc Value) { unsigned char ucControlByte; outportb(LPTDATA, ucValue); switch (iPortNum) { case PORTA: ucControlByte = 0x07; break; case PORTB: ucControlByte = 0x06; break; case PORTC: ucControlByte = 0x05; break; case PORTCNTL: ucControlByte = 0x04; } outportb(LPTCONTROL, ucControlByte); // Sets port address outportb(LPTCONTROL, ucControlByte | 0x08); // Strobe !WR low outportb(LPTCONTROL, ucControlByte) ; // Set ! WR high again outportb(LPTCONTROL, 0x07); // Set back to initial state return; } unsigned char in(int iPortNum) { unsigned char ucControlByte, ucValue, ucValue2; switch (iPortNum) { // Set port Addr & Dir to input case PORTA: ucControlByte = 0x27; break; case PORTB: ucControlByte = 0x26; break; case PORTC: ucControlByte = 0x25; break; case PORTCNTL: ucControlByte = 0x24; -13mm- } outportb(LPTCONTROL, ucControlByte); // Sets port address outportb(LPTCONTROL, ucControlByte & OxFB); // Strobe !RD low ucValue = inportb(LPTDATA); // Read value from port if (ucValue = = 0); // Dummy statement ucValue = inportb(LPTDATA); // Read value from port bool agree = 0; while (! agree) { ucValue2 = inportb(LPTDATA); // Read value from port if (ucValue2 = = ucValue) agree = 1 ; else ucValue = ucValue2; } outportb(LPTCONTROL, 0x07); // Set back to initial state return ucValue; } -13nn- ** LPT-8255.h Header file for Parallel printer port to 8255 I/O functions. Created 4/29/97 by Tom Hawkins */ #define LPTDATA 0x378 // LPT Port Data bits DO - D7 #define LPTSTATUS LPTDATA + 1 // LPT Port Inputs, not used #define LPTCONTROL LPTDATA +2 // LPT Port Control signals #define LPTECR LPTDATA +0x402 // ECP port Extended Control Register // Bit 0 - AO, 8255 port address (inverted) // Bit 1 - Al, 8255 port address (inverted) // Bit 2 - !RD, 8255 control line // Bit 3 - !WR, 8255 control line (inverted) // Bit 4 - Interrrupt control, 0=Disabled, l =Enabled // Bit 5 - Direction control, 0= Outputs, 1 = Inputs // Initial value: 0000 0111 = 0x07; !RD, !WR high, A0, Al low #define PORTA 0 // 8255 Ports #defιne PORTB 1 #define PORTC 2 #define PORTCNTL 3 void init8255(void); void out(int, unsigned char); unsigned char in(int);

Claims: -14- Claims: 1. A method of applying verification markings on a progressive ophthalmic lens which comprises the steps of: providing a stage, wherein positions of the stage are identifiable in a coordinate system; attaching the lens to the stage; locating two reference marks on the surface of the lens; identifying the positions of the two reference marks by coordinates; utilizing the coordinates of the two reference marks in a computer which includes a database containing the coordinates of the verification markings for the lens; positioning the lens under a pen ; calibrating the position of the pen; and applying the verification markings on the lens surface with the pen wherein the verification markings are produced by movement of the (i) stage, (ii) pen, or (iii) both the stage and pen and wherein said movement is controlled by the computer. 2. The method of claim 1 wherein the database contains the coordinates for more than one set of verification markings and the method includes the step of selecting a set of verification markings to be applied. 3. The method of claim 1 wherein the step of locating the two reference marks comprises locating the two marks with a microscope. 4. The method of claim 3 wherein the microscope comprises an eyepiece with a cross hair reticle. -15- 5. The method of claim 1 wherein the verification markings comprise markings selected from the group consisting of a major reference point, axis line, lens fitting cross, distance power measuring circle, add power measuring circle, and mixtures thereof. 6. The method of claim 1 wherein verification markings comprise ink mark patterns. 7. The method of claim 1 wherein the calibration step comprises the steps of: creating a point mark on the lens surface; determining the coordinates that correspond to the point mark and utilizing these coordinates in the computer; and correlating the position of the pen relative to the position of the point mark. 8. The method of claim 2 wherein the calibration step comprises the steps of: creating a point mark on the lens surface; determining the coordinates that correspond to the point mark and utilizing these coordinates in the computer; and correlating the position of the pen relative to the position of the point mark. 9. The method of claim 1 wherein the stage is movable within a plane and the step of positioning the pen comprises moving the stage. 10. The method of claim 1 wherein said movement is guided by coordinate transformations determined by locating the reference marks. -loll. A device for restoring verification markings on a progressive ophthalmic lens which comprises: a stage which defines a coordinate system and which is adapted for receiving the ophthalmic lens; a magnifying device for locating reference marks on the ophthalmic lens surface; a computer having a database containing the coordinates of verification markings for the progressive ophthalmic lens; and a pen adapted to be positioned over the surface of the ophthalmic lens wherein movement of the (i) stage, (ii) pen, or (iii) both the stage and pen are controlled by the computer in producing the verification markings on the ophthalmic lens surface. 12. The device of Claim 11 wherein the database contains the coordinates for more than one set of verification markings. 13. A method of applying verification markings on a mold used for casting a progressive ophthalmic lens which comprises the steps of: providing a stage wherein positions of the stage are identifiable by a coordinate system; placing the mold on the stage; locating two recesses on the surface of the mold which correspond to reference marks on the lens; identifying the positions of the two recesses by their coordinates; utilizing the coordinates of the two recesses in a computer which includes a database containing the coordinates of the verification markings for the mold; positioning the mold under a pen; calibrating the position of the pen; and -17- applying the verification markings on the mold surface with the pen wherein the verification markings are produced by movement of the (i) stage, (ii) pen, or (iii) both the stage and the pen and wherein said movement is controlled by the computer. 14. The method of claim 13 wherein the database contains the coordinates for more than one set of verification markings and the method includes the step of selecting a set of verification markings to be applied. 15. The method of claim 13 wherein the step of locating the two recesses comprises locating the two recesses with a microscope with an eyepiece having cross hairs. 16. The method of claim 13 wherein the stage is movable within a plane and the step of moving the stage. 17. The method of claim 13 wherein the verification markings comprise markings selected from the group consisting of a major reference point, axis line, lens fitting cross, distance power measuring circle, add power measuring circle, and mixtures thereof. 18. The method of claim 13 wherein verification markings comprise ink mark patterns. 19. The method of claim 13 wherein the calibration step comprises the steps of: creating a point mark on the lens surface; -18- determining the coordinates that correspond to the point mark and utilizing these coordinates in the computer; and correlating the position of the pen relative to the position of the point mark. 20. The method of claim 14 wherein the calibration step comprises the steps of: creating a point mark on the lens surface; determining the coordinates that correspond to the point mark and utilizing these coordinates in the computer; and correlating the position of the pen relative to the position of the point mark. 21. The method of claim 13 wherein said movement is guided by coordinate transformations determined by locating the reference marks. 22. A device for producing verification markings on a mold used for casting a progressive ophthalmic lens which comprises: a stage which defines a coordinate system and which is adapted for receiving the mold; a magnifying device for locating recesses on the mold surface which correspond to reference marks on the lens; a computer having a database containing the coordinates of the verification markings for the progressive ophthalmic lens mold; and a pen adapted to be positioned over the surface of the mold wherein movement of the (i) the stage, (ii) pen, or (iii) both the stage and pen are controlled by the computer. 23. The device of claim 22 wherein the database contains the coordinates for more than one set of verification markings.

Inventors: HAWKINS THOMAS J, WEIR ROBERT P, HAWKINS, THOMAS, J., WEIR, ROBERT, P.
Applicants: HAWKINS THOMAS J, SOLA INTERNATIONAL INC, WEIR ROBERT P, HAWKINS, THOMAS, J., SOLA INTERNATIONAL, INC., WEIR, ROBERT, P.
Application year: 1998
Main classification: B43L11
IPC codes: G01M11, G02C7