WO1997042607A2 - Apparatus and method for generating a sheet metal bending plan - Google Patents

Apparatus and method for generating a sheet metal bending plan Download PDF

Info

Publication number
WO1997042607A2
WO1997042607A2 PCT/US1997/007473 US9707473W WO9742607A2 WO 1997042607 A2 WO1997042607 A2 WO 1997042607A2 US 9707473 W US9707473 W US 9707473W WO 9742607 A2 WO9742607 A2 WO 9742607A2
Authority
WO
WIPO (PCT)
Prior art keywords
faces
entities
coordinate space
bendline
information
Prior art date
Application number
PCT/US1997/007473
Other languages
French (fr)
Other versions
WO1997042607A3 (en
Inventor
Kensuke Hazama
Kalev Kask
Satoshi Sakai
Moshe Edward Schwalb
Original Assignee
Amada Metrecs Co., Ltd.
Amadasoft America, Inc.
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Amada Metrecs Co., Ltd., Amadasoft America, Inc. filed Critical Amada Metrecs Co., Ltd.
Priority to DE69737913T priority Critical patent/DE69737913T2/en
Priority to EP97925441A priority patent/EP1038272B1/en
Publication of WO1997042607A2 publication Critical patent/WO1997042607A2/en
Publication of WO1997042607A3 publication Critical patent/WO1997042607A3/en

Links

Classifications

    • GPHYSICS
    • G05CONTROLLING; REGULATING
    • G05BCONTROL OR REGULATING SYSTEMS IN GENERAL; FUNCTIONAL ELEMENTS OF SUCH SYSTEMS; MONITORING OR TESTING ARRANGEMENTS FOR SUCH SYSTEMS OR ELEMENTS
    • G05B19/00Programme-control systems
    • G05B19/02Programme-control systems electric
    • G05B19/18Numerical control [NC], i.e. automatically operating machines, in particular machine tools, e.g. in a manufacturing environment, so as to execute positioning, movement or co-ordinated operations by means of programme data in numerical form
    • G05B19/4097Numerical control [NC], i.e. automatically operating machines, in particular machine tools, e.g. in a manufacturing environment, so as to execute positioning, movement or co-ordinated operations by means of programme data in numerical form characterised by using design data to control NC machines, e.g. CAD/CAM
    • GPHYSICS
    • G05CONTROLLING; REGULATING
    • G05BCONTROL OR REGULATING SYSTEMS IN GENERAL; FUNCTIONAL ELEMENTS OF SUCH SYSTEMS; MONITORING OR TESTING ARRANGEMENTS FOR SUCH SYSTEMS OR ELEMENTS
    • G05B19/00Programme-control systems
    • G05B19/02Programme-control systems electric
    • G05B19/418Total factory control, i.e. centrally controlling a plurality of machines, e.g. direct or distributed numerical control [DNC], flexible manufacturing systems [FMS], integrated manufacturing systems [IMS], computer integrated manufacturing [CIM]
    • G05B19/4181Total factory control, i.e. centrally controlling a plurality of machines, e.g. direct or distributed numerical control [DNC], flexible manufacturing systems [FMS], integrated manufacturing systems [IMS], computer integrated manufacturing [CIM] characterised by direct numerical control [DNC]
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06QINFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES; SYSTEMS OR METHODS SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES, NOT OTHERWISE PROVIDED FOR
    • G06Q10/00Administration; Management
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06QINFORMATION AND COMMUNICATION TECHNOLOGY [ICT] SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES; SYSTEMS OR METHODS SPECIALLY ADAPTED FOR ADMINISTRATIVE, COMMERCIAL, FINANCIAL, MANAGERIAL OR SUPERVISORY PURPOSES, NOT OTHERWISE PROVIDED FOR
    • G06Q10/00Administration; Management
    • G06Q10/06Resources, workflows, human or project management; Enterprise or organisation planning; Enterprise or organisation modelling
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06TIMAGE DATA PROCESSING OR GENERATION, IN GENERAL
    • G06T19/00Manipulating 3D models or images for computer graphics
    • G06T19/20Editing of 3D images, e.g. changing shapes or colours, aligning objects or positioning parts
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06TIMAGE DATA PROCESSING OR GENERATION, IN GENERAL
    • G06T7/00Image analysis
    • G06T7/40Analysis of texture
    • G06T7/41Analysis of texture based on statistical description of texture
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06VIMAGE OR VIDEO RECOGNITION OR UNDERSTANDING
    • G06V10/00Arrangements for image or video recognition or understanding
    • G06V10/40Extraction of image or video features
    • G06V10/42Global feature extraction by analysis of the whole pattern, e.g. using frequency domain transformations or autocorrelation
    • G06V10/422Global feature extraction by analysis of the whole pattern, e.g. using frequency domain transformations or autocorrelation for representing the structure of the pattern or shape of an object therefor
    • G06V10/426Graphical representations
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06TIMAGE DATA PROCESSING OR GENERATION, IN GENERAL
    • G06T2200/00Indexing scheme for image data processing or generation, in general
    • G06T2200/24Indexing scheme for image data processing or generation, in general involving graphical user interfaces [GUIs]
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06TIMAGE DATA PROCESSING OR GENERATION, IN GENERAL
    • G06T2207/00Indexing scheme for image analysis or image enhancement
    • G06T2207/30Subject of image; Context of image processing
    • G06T2207/30108Industrial image inspection
    • G06T2207/30136Metal
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06TIMAGE DATA PROCESSING OR GENERATION, IN GENERAL
    • G06T2219/00Indexing scheme for manipulating 3D models or images for computer graphics
    • G06T2219/20Indexing scheme for editing of 3D models
    • G06T2219/2021Shape modification
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06VIMAGE OR VIDEO RECOGNITION OR UNDERSTANDING
    • G06V2201/00Indexing scheme relating to image or video recognition or understanding
    • G06V2201/06Recognition of objects for industrial automation
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02PCLIMATE CHANGE MITIGATION TECHNOLOGIES IN THE PRODUCTION OR PROCESSING OF GOODS
    • Y02P90/00Enabling technologies with a potential contribution to greenhouse gas [GHG] emissions mitigation
    • Y02P90/02Total factory control, e.g. smart factories, flexible manufacturing systems [FMS] or integrated manufacturing systems [IMS]
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y10TECHNICAL SUBJECTS COVERED BY FORMER USPC
    • Y10STECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y10S707/00Data processing: database and file management or data structures
    • Y10S707/99941Database schema or data structure
    • Y10S707/99944Object-oriented database structure

Definitions

  • the present invention relates to an apparatus and method for managing and distributing design and
  • bent sheet metal components at, for example, a
  • the first stage is a design stage during which a sheet metal part
  • the component may be manufactured by the factory.
  • This information may include, for
  • the geometric dimensions of the part e.g., the geometric dimensions of the part, the material required for the part (e.g., steel, stainless steel, or aluminum), special forming information, the batch size, the delivery date,
  • the sheet metal part requested by the customer may be designed and produced for a
  • the produced component may ultimately be used
  • a sheet metal part design may be developed by the design
  • metal part may be developed by a programmer with the CAD system. Typically, a customer
  • the blueprint may also indicate any special forming or
  • the design programmer will often use this blueprint to develop a 2-D model on the CAD system.
  • the 2-D model may include a flat
  • CNC Computer Numerical Control
  • NC Numerical Control
  • CAM Computer-Aided Manufacturing
  • CAD/CAM system can be used by a design programmer to generate control code based on
  • control code may comprise a part program that is imported to and
  • the next stage in the production process is a bending plan stage.
  • a bending plan is developed by a bending operator at the shop floor. The operator will
  • the bending workstation may include CNC metal bending
  • One of the final stages in the production process is the bending stage.
  • Job scheduling is also performed in order to ensure that
  • Job scheduling may be developed or modified by a shop floor foreman during the earlier
  • the final bent sheet metal parts have been produced, the parts may then be assembled and
  • manufacturing data for each customer's order is normally archived physically (e.g., by paper
  • distribution of critical job information takes the form of a paper job or work sheet that is
  • component may be provided to the shop floor operator to assist in the development of the
  • the present invention through one or more of its
  • a general object of the present invention is to provide an apparatus and method for
  • a further object of the present invention is to provide an apparatus and method that
  • Another object of the invention is to provide an apparatus and method for logically
  • Yet another object of the present invention is to provide an apparatus and method
  • the job data may provide not only the design and manufacturing information associated with the job, but also the
  • Still another object of the present invention is to provide an apparatus and method
  • the search criteria may include, for example, the basic
  • job information relating to an identical or similar part can be utilized to reduce the overall
  • Another object of the present invention is to replace the traditional paper job or work
  • the electronic job sheet may be
  • the electronic job sheet may also include an audio and or video portion recorded by a bending operator to indicate, for example, any
  • Another object of the invention is to shorten the time required to analyze a part
  • viewing modes may be provided, including a solid 3-D viewing mode, a 3-D wire frame
  • a 2-D flat screen viewing mode a 2-D flat screen viewing mode
  • an orthographic viewing mode a 2-D flat screen viewing mode
  • Different viewing functions may also be provided, including zooming, panning, rotating and
  • a further object of the invention is to provide an apparatus and method that facilitates the development of the sheet metal part design and bending plan by the design
  • the present invention is directed to an apparatus and method for
  • the apparatus may
  • a face detecting system may also be provided for detecting, within the first
  • the faces of the part based on the initial part information.
  • the apparatus may include a bendline identification system for identifying at least one bendline of the part based on the detected faces, and a system for generating
  • operation may be performed based upon at least the initial part information and at least one
  • bendline identified by the bendline identification system
  • the first predetermined coordinate space may comprise a 2-D coordinate space
  • the second predetermined coordinate space may comprise a 3-D coordinate space, wherein
  • the predetermined operation comprises a folding operation performed on the faces detected by the face detecting system.
  • the folding operation may include rotating and translating
  • each of the faces detected by the face detecting system relative to at least one bendline
  • the initial part information may be
  • the predetermined operation comprises an
  • unfolding operation may include rotating and translating each of the faces detected by the
  • the initial part information may further comprise a bend
  • the part to be produced may comprise a sheet metal part, and the data relating to a representation of the part within the first predetermined coordinate space may include
  • the faces of the part may comprise the base
  • the initial part information may
  • the thickness data of the part in 3-D coordinate space may include thickness data of the part in 3-D coordinate space.
  • the apparatus for developing a bend model may also include an auto-trimming and
  • the data may comprise part entity data representing, at least, line entities and bendline entities of the part, and the auto-trimming and cleanup system may
  • auto-trimming and cleanup system may also comprise a system for detecting open
  • intersection areas between adjacent entities and for selectively connecting the adjacent
  • Open intersection areas may be detected, by the system for detecting open
  • intersection areas when the endpoints of the adjacent entities are determined to be within
  • part entity data representing, at least, line entities of the part
  • the face detecting system may be adapted to perform a loop and entity analysis of the part
  • the loop and entity analysis may initially be performed on an outside boundary of the part and then performed on inner
  • the face detecting system may generate an initial linked
  • the face detecting system may further generate an additional linked list of entities
  • the face detecting system may further comprise a system for generating a loop
  • the face detecting system may
  • the bendline identification system of the invention may comprise a system for
  • Bendlines may be identified based on the detection of one of the faces having only one common line entity with another one of the faces. In addition, the bendline identification
  • system may apply predetermined heuristics to identify bendlines of the part when the system
  • the heuristics may comprise identifying bendlines of the part such
  • the heuristics may
  • a system for calculating the amount of the part may be provided to receive a deduction amount related to the part.
  • the system for compensating for bend deduction may also be adapted to decrease
  • the method for developing a bend model may comprise the following steps: receiving initial part information relating to the part, the initial part information including
  • the first predetermined coordinate space may comprise a 2-D coordinate space
  • the second predetermined coordinate space may comprise a 3-D coordinate space.
  • the method may further comprise performing a folding operation on the faces
  • the folding operation may include rotating and translating
  • the initial part information may comprise a bend angle amount relating to at least
  • space may comprise a 3-D coordinate space and the second predetermined coordinate space
  • the method may comprise a 2-D coordinate space.
  • the method may also further comprise performing
  • operation may include rotating and translating each of the faces relative to at least one
  • the initial part information may
  • the method may also comprise performing an auto-trimming and cleanup operation
  • the data of the initial part information may comprise part entity data
  • the loop and entity analysis may initially performed on an
  • the step of identifying may further comprise
  • the heuristics may comprise identifying
  • bendlines of the part such that a minimum number of total bendlines are identified for the
  • the heuristics may also comprise identifying bendlines of the part, when one of the
  • faces have more than one common line entity with another one of the faces, based on the common line entity that has the longest length.
  • the present invention also encompasses a system for developing a bend model of a
  • part to be produced in a production facility, wherein the part includes a plurality of faces and
  • the system comprises means for receiving initial part information
  • the initial part information including data relating to a
  • Detecting means means
  • the system may also include means
  • predetermined operation may be performed based on, at least in part, the bendline identified
  • system may comprise a receiving system for receiving initial part information relating to the
  • the initial part information comprises respective representations of a plurality
  • each of the representations include part
  • a cleanup operation system may also be provided to
  • the system may also include a part
  • thickness elimination system for selectively eliminating the part thickness representations in each of the identified representations to provide modified representations of the views of the part in 2-D coordinate space with no thickness, and a system for developing a
  • the initial part information may comprise part entity data representing, at least, line
  • the cleanup operation system may include a break and trimming
  • break and trimming system may assign
  • the break and trimming system may further comprise a system for detecting open
  • intersection areas between adjacent entities and for selectively connecting the adjacent
  • Open intersection areas may be detected, by the system for detecting open intersection areas,
  • the cleanup operation system In accordance with another aspect of the invention, the cleanup operation system
  • unconnected line entities may comprise unconnected line entities, wherein the unconnected line entities relating to,
  • the initial part information may also comprise key words for identifying part entity
  • the cleanup operation system may
  • the cleanup operation system may
  • the top view, the front view, and the right side view of the part As disclosed herein, the
  • plurality of views of the part may comprise a top view, a front view, and a right side view
  • the developing system may include a
  • projection operation may comprise detecting the relative depths of each of the plurality of
  • the method for developing a bend model may comprise the steps of: receiving initial
  • the initial part information comprising respective
  • part in 3-D coordinate space based on the modified representations of the part in 2-D
  • the initial part information may comprise part entity data representing, at least, line
  • the step of performing may comprise detecting intersection points
  • the step of performing may also comprise detecting open intersection areas between adjacent entities and selectively connecting the adjacent entities by assigning
  • Open intersection areas may be detected when
  • the endpoints of the adjacent entities are within a predetermined distance from one another.
  • the method may also comprise the steps of developing a connectivity graph structure
  • the extraneous information may be part information based on the connectivity graph structure.
  • the extraneous information may be
  • unconnected line entities the unconnected line entities relating to. at least, dimension lines.
  • the initial part information may comprise key words for identifying part entity
  • step of performing includes the
  • part thickness may comprise prompting a user to identify the part thickness representations
  • the dimension of the part may comprise one
  • the projection operation may include detecting the relative depths of each of the
  • the invention may be directed to various combinations and subcombinations
  • Fig. IA is a block diagram illustration of a progressive sheet metal manufacturing
  • Fig. IB is a block diagram illustration of a progressive sheet metal manufacturing
  • Fig. 2 illustrates the respective data flow between the server module, database and
  • Fig. 3 is a flow chart of the general processes and operations that may be performed
  • Fig.4 is a representative flow chart of the basic processes and operations that may
  • Figs. 5 A and 5B are flowcharts that illustrate the logic flow of a similar part search
  • Figs. 6A, 6B, 6C, 6D, 6E, 6F and 6G illustrate, in accordance with an aspect of the
  • Figs. 7A, 7B and 7C illustrate, in accordance with another aspect of the present invention, a feature relation operation and process for identifying search keys for a part
  • Fig. 8 is a flow chart that illustrates the logic flow of the processes and operations
  • Figs. 9A, 9B, 9C, 9D and 9E illustrate examples of an auto-trimming function
  • Figs. 10A, 10B, IOC, 10D, 10E, 10F, 10G, and 10H illustrate the various processes
  • Figs. 1 IA and 1 IB illustrate the development of a final bend graph data structure
  • Fig. 12 is a flow chart of the basic logic flow for developing a 2-D model based on
  • Fig. 13 is a flow chart of the basic logic flow for developing a 3-D model based on
  • Fig. 14A is a flow chart, according to an aspect of the invention, of the basic logic
  • Figs. 14B and 14C illustrate views and aspects of an exemplary 2-D, three view
  • Fig. 14D illustrates a rotated view feature of the 2-D clean-up operation of the
  • FIG. 14E illustrates, in accordance with an aspect of the present invention, a
  • Figs. 15 A and 15B illustrate an example of a 2-D, three view drawing with thickness
  • Fig. 15C is an illustration of a cross thickness line and thickness arc of an exemplary
  • Fig. 16 is a flow chart of the logic flow of the various processes and operations that
  • Fig. 17 illustrates an exemplary data structure and access algorithm of the bend
  • Fig. 18 illustrates a block diagram of the structure of the bend model viewer, in
  • Fig. 19 illustrates an exemplary solid view window display that may be provided as
  • Fig. 20 illustrates an exemplary wire frame view window display that may be
  • Fig. 21 illustrates a 2-D flat screen image window display that may be provided as
  • Fig. 22 illustrates an orthographic view screen image that may be provided as output to a display screen
  • Fig. 23 illustrates an example of the various dimension items that may be displayed in an automatic dimension mode of the present invention
  • Figs. 24A, 24B and 24C illustrate a manner in which the flange length may be
  • Figs. 25A and 25B illustrate, in accordance with another aspect of the present
  • Figs. 26A, 26B and 26C illustrate a manner in which the flange length may be
  • Figs. 27A and 27B illustrate manners in which the flange length of parts with acute bend angles may displayed, in accordance with a tangent dimension method and an
  • Fig. 28 is a flow chart of the logic flow of the processes and operations that may be
  • Fig. 29A illustrates an example of a bend sequence input screen image that may be
  • Figs. 29B and 29C illustrates examples of selection a bend sequence and modifying
  • Figs.29D and 29E illustrate further examples of a bend sequence input screen image
  • Fig. 30 illustrates, in accordance with an aspect of the present invention, a drag and
  • drop editing feature that may be provided to facilitate a bending operator in modifying
  • Fig. 31 illustrates an example of the various display menus and data tables that may be graphically displayed to aid a bending operator in selecting tooling
  • Fig. 32 illustrates an exemplary tool set-up window that may be displayed to a
  • Fig. 33 A illustrates an example of a 3-D solid view window display with audio
  • Fig. 33B illustrates another example of a display window that may be inco ⁇ orated
  • Fig. 34 illustrates an example of an image editing window that may be implemented
  • Figs. 35 A and 35B illustrate examples of a collision check function of the present
  • Figs.36A and 36B illustratea manipulation system of the invention for manipulating
  • Fig. 37 illustrates a manipulation system of the invention for manipulating the
  • Fig. 38 illustrates a manipulation system of the invention for manipulating the
  • Fig. 39 is an exemplary flow chart of the processes and operations that may be
  • Fig.40 illustrates an example of mapping joystick movements to cursor movements, in accordance with an aspect of the invention
  • Fig. 41 is an exemplary flow chart of the processes and operations that may be
  • Fig.42 illustrates an example of a main menu window display that may be provided
  • Fig. 43 illustrates an exemplary part information window display that may be
  • Fig. 44 illustrates an exemplary bendline information window display that may be
  • Fig. 45 illustrates an exemplary bend sequence window display of the present invention for viewing the intermediate bend stages of a sheet metal part
  • Fig.46 illustrates an exemplary bend simulation window display of the invention for
  • Fig. 47 is an exemplary menu screen diagram and structure of the present invention
  • Fig. 48 is an exemplary menu screen diagram and structure for a 2-D clean-up
  • Fig. 49A illustrates an example of a 3-D representation of a part before one sided
  • Fig. 49B illustrates the part after the one sided open lines have
  • Fig. 50A illustrates an exemplary 3-D representation of a part before the bendlines
  • Fig. 50B illustrates the part after the mold lines have been added, according to a 3-D clean-up process of the invention.
  • Fig. 51 A illustrates an exemplary section of a part before cleaning the bendlines
  • Fig. 5 IB shows the section of the part after cleaning and trimming
  • Appendix A is an exemplary source code for executing a feature extraction operation
  • Appendix C is an exemplary source code for performing a bendline detection
  • Appendix D is an exemplary source code for implementing a 2-D cleanup operation
  • Appendix E is an exemplary source code for implementing the various view modes
  • Appendices F, G, H and I are exemplary source code and comments relating to
  • Appendix J is an exemplary source code for implementing a part and entity visibility function of the bend model viewer of the invention.
  • Appendix K includes general comments relating to the implementation of the bend
  • Appendix L includes exemplary source code for implementing a 3-D manipulation
  • an apparatus and method are provided. According to an aspect of the present invention, an apparatus and method are provided.
  • a progressive sheet metal manufacturing facility 38 is generally
  • the sheet metal manufacturing facility or factory 38 may include a
  • locations may comprise a design office 10, an assembly station 12, a shipping station 14, a
  • Fig. IA metal factory 38 in Fig. IA is depicted as having only six discrete locations, the factory may
  • factory 38 may include more than one design office 10, assembly station 12 or shipping
  • station 14 may also include other types of locations for facilitating the production and
  • Each of the locations 10, 12, 14...20 within the factory 38 may be adapted and
  • the design office 10 may include an appropriate CAD/CAM system, to
  • the CAD/CAM system may comprise one or more personal computers, a display unit, a printer, and commercially available CAD/CAM software.
  • a display unit may comprise one or more personal computers, a display unit, a printer, and commercially available CAD/CAM software.
  • the CAD/CAM system of the design office 10 may include AUTOCAD or
  • VELLUM which is a Windows based CAD system available from Ashlar Inco ⁇ orated.
  • the design programmer may develop a 2-D model and/or 3-D
  • the design programmer may also generate control code based on the sheet metal part
  • Punching station 16 and bending station 18 may, each be provided with any combination of CNC and/or NC based machine tools.
  • CNC and/or NC punch presses such as COMA series and/or
  • punch presses and bending station 18 may include one or more CNC and/or NC press
  • RG series Amada press brakes such as RG series Amada press brakes or other commercially available multiple-axis
  • welding station 20 may be provided with appropriate welding
  • Punching station 16, bending station 18 and welding station 20 may be located at various locations
  • Fully automated or robot assisted machinery such as the Amada CELLROBO MINI and the Amada
  • PROMECAM may also be provided at these locations. The required punching and bending
  • the progressive sheet metal facility 38 may also include
  • Assembly station 12 and shipping station 14 Assembly station 12 and shipping station 14
  • assembly station 12 and shipping station 14 may be physically located near the factory floor
  • the management and distribution of critical design and manufacturing information is achieved by electronically
  • each of the locations 10, 12, 12...20 may be any of the locations 10, 12, 12...20.
  • station modules that interface with communications network 26 and database 30.
  • Figs. IA, IB and 2 illustrate non-limiting examples of these features and implementation
  • communications network 26 may interconnect each
  • Communications network 26 may comprise any network capable of transmitting data
  • Such transmission may be achieved electronically, optically, by RF
  • communications may be transmitted or by infrared transmission.
  • communications may be transmitted or by infrared transmission.
  • LAN Local Area Network
  • Ethernet or an equivalent
  • each of the locations 10, 12, 14...20 may also include station modules having network terminating equipment (such as a computer,
  • minicomputeror workstation and/or peripheral devices (such as a display monitor or screen,
  • printers CD-ROMs, and/or modems
  • the computer may be a stand-alone, personal computer or a general pu ⁇ ose computer that
  • the computer may be an IBM compatible personal computer or may be a computer that is part of an interface/control system of the machinery, such as an Amada AMNC
  • Server module 32 and database 30 are also connected to communications network
  • Server module 32 may comprise network terminating equipment, such as a personal
  • Server module 32 may also include software or firmware
  • server module
  • 32 may also include database 30 for storing the design and manufacturing information
  • Database 30 may be implemented by any combination
  • database 30 may comprise a SCSI memory disk with 4 GB or more
  • the design and manufacturing information that is stored in database 30 may be accessed and distributed to the various locations 10, 12, 14...20 within
  • SQL Structured Query Language
  • database 30 information that is stored in database 30 may be backed-up and stored on
  • Server module 32 and database 30 may be connected to communications network 26 at a
  • predefined stations within or in close proximity to one of the predefined stations (e.g., within design office 10).
  • Fig. 1 A depicts database 30 as being part of server module 32
  • database 30 may of course be physically located separately from server module 32 and connected to
  • server module 32 and each of the locations 10, 12, 14...20 may
  • a personal computer such as an IBM compatible computer with a 100-200 MHz
  • CPU central processor unit
  • Pentium or an equivalent microprocessor
  • a joystick or mouse device may also include a Sound Blaster or compatible sound and
  • game port adapter card for interfacing and controlling the display of information.
  • system software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • server software may also be provided to support communications.
  • module 32 may be provided with Microsoft Windows New Technology (NT) or Windows
  • server module 32 and locations 10, 12, 14...20
  • OLE2 Object Linking and Embedding
  • a database language such as
  • SQL Structured Query Language
  • SQL Server which is a retail product available from
  • ODBC Open Database Connectivity
  • Fig. 1 B illustrates, in block diagram form, a progressive sheet metal manufacturing
  • the database 30 being connected to communications network 26 via a network database
  • the database 30 and server module 32 may be provided together (as shown, e.g., in Fig. 1 A),
  • station module 36 illustrates an example of the station module 36 that may be provided at each of the various components
  • an exemplary station module 36 that may be located at bending station 18 is
  • modules 36 may also be provided at the other locations within the facility 38.
  • each of the modules i.e., server module 32, network database
  • module 34 may be connected to communications network 26 via a
  • the network interface card 26 may be vendor specific and
  • modules 32, 34 and 36 may also include network software or programmed logic for
  • the communicationsnetwork 26 may be
  • Ethernet with any of a number of commercially available cable types, such as 10 Base/T
  • server module 32 may comprise a personal computer 40 with display
  • monitor or CRT 44 and input/output devices 46 which may include a keyboard, mouse
  • the network interface card 42 may be plugged into an available expansion
  • personal computer 40 may comprise
  • Personal computer 40 may also include, for example, 32 MB or more
  • RAM random access memory
  • Display 44 may include a high resolution display screen, such as any commercially available
  • SVGA monitor with, for example, 800 x 600 resolution.
  • personal computer 40 may also display information that may be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also display information that may be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40 may also be displayed on display 44, personal computer 40
  • Computer 40 may include a Sound Blaster or compatible sound and game port adapter card and input output devices 46 may include a keyboard, joystick and/or mouse device.
  • server module 32 may
  • server module may be configured with software and various software packages.
  • server module may be configured with software and various software packages.
  • server module
  • operating system software such as Microsoft Windows NT
  • server module 32 may
  • routines may be developed using a high level programming language, such as
  • Server module 32 may also include or
  • CAD or CAD/CAM software such as VELLUM or Amada AP40 or AP60
  • server module may be located in the design office 10 of the
  • server module 32 may
  • OBDC driver such as Microsoft ODBC driver
  • SQL SQL
  • OLE server such as OLE2 server, may also be provided to any standard for accessing data.
  • OLE server such as OLE2 server, may also be provided to any standard for accessing data.
  • database 30 is provided separate from server module
  • database 30 may comprise a SCSI disk with appropriate memory space
  • Network database module 34 may include a
  • personal computer 40 such as an IBM compatible computer with a Pentium microprocessor
  • Database 30 may be connected to personal computer 40 via a data bus and personal computer 40 may include standard display and input/output devices
  • a display monitor or CRT such as a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display (LCD), a liquid crystal display, or a display monitor or CRT and a keyboard.
  • network database module 34 may be configured with a commercially available SQL server,
  • OLE server such as OLE2
  • Personal computer 40 may also be provided to link the data.
  • Personal computer 40 may also be configured
  • DOS DOS
  • Microsoft Windows NT server version
  • Fig. IB also includes an exemplary implementation of one
  • station module 36 In this embodiment, the station module 36 is implemented at bending
  • the station module 36 may include similar hardware to that of the server module 32. That is, each station module (e.g., at the other stations shown in
  • Fig. 1 A may comprise a computer 48 with display monitor or CRT 44 and input output
  • the network interface card 42 may be
  • the computer of the station module 36 may be a stand-alone, personal computer or a general
  • pu ⁇ ose computer that is part of an interface device of the equipment or machinery provided
  • computer 48 may comprise a free-standing, personal computer
  • Pentium Pro microprocessor, or computer 48 may be a computer that is part of or built into
  • an interface/control system of the machinery such as an Amada AMNC system.
  • 48 may also include, for example, 32 MB or more of available main memory and 1.2 GB
  • Display 44 may include a high
  • resolution display screen such as any commercially available SVGA monitor with, for
  • computer 48 may also include any commercially available
  • computer 48 may include a Sound
  • station module 36 may
  • station also be configured with software and various software packages.
  • station also be configured with software and various software packages.
  • station also be configured with software and various software packages.
  • station also be configured with software and various software packages.
  • station also be configured with software and various software packages.
  • station also be configured with software and various software packages.
  • station
  • module 36 may be provided with operating system software, such as Microsoft Windows
  • station module 36 may
  • routines may be developed using a high level programming language, such as
  • station In order to access and link data, station
  • module 36 may also include an OBDC driver, such as Microsoft ODBC driver, and an OLE
  • station module may use SQL as
  • station module 36 of bending station 18 is provided as a free-standing personal
  • NC data bending code data
  • machinery 25 e.g., a CNC
  • This interface may be
  • station module 36 provided to permit the station module 36 to communicate with and send or receive bending
  • the bending machinery 25 should thus be formatted based on the machine instruction set that
  • the computer 48 of station module 36 may also be provided
  • NC systems such as a Amada AMNC for such machinery.
  • Fig. 2 illustrates an exemplary embodiment of the respective data flows between
  • server module 32 database 30 and the various locations of the sheet metal manufacturing
  • server module 32 and database 30 integrated with
  • network database module 34 are each shown in Fig. 2 as being separately and directly
  • the data and information can be directly transferred from the server module to the database
  • the design and manufacturing information associated with each customer's order may be organized and stored in database 30.
  • basic product and design information may be entered at server module 32 and then
  • server module 32 may include
  • any suitable means for entering the data such as a personal computer with a keyboard, etc.
  • server module 32 software may be provided to generate
  • program may be, for example, a Microsoft Windows based application with help and/or
  • bend model data feature extraction data, and bend line information, as generally illustrated
  • the part information may comprise, for example, a part or order reference number,
  • the bend model data may include, for example, part geometry and
  • manufacturing data such as the overall dimensions of the part (e.g., width, height, depth),
  • part material information such as the material type (e.g., steel, stainless steel, or
  • feature extraction data may be manually
  • data may be stored in a separate data file in database 30, or may be stored with the bend
  • the feature extraction data may be
  • bends present e.g., a positive bend between two faces or a negative bend
  • such data may be represented and organized in a feature based part matrix and/or a sequence of search keys (see, e.g., Figs.
  • bend line information may be entered at server module 32 for storage
  • the bend line information may comprise, for example, pertinent bend line
  • IR radius of the bend
  • amount of deduction the amount of deduction
  • bend direction e.g., front or back
  • each of the locations 10, 12, 14...20 may comprise a station module (such as
  • Fig. 2 punching station 16 and bending station 18 are generally illustrated in block diagram
  • the station module may comprise, for
  • the design and manufacturing information including the part information,
  • bend line information, and bend model data may be accessed and retrieved by entering, for example, a predetermined reference number or code.
  • the reference number or code may be
  • previous job data may be accessed and retrieved from
  • search may be conducted based on the feature extraction data or search keys stored in
  • the design and manufacturing information that is retrieved from database 30 may be used by the shop floor operators to develop and test the bending plan. For example, a
  • bending operator at bending station 18 may access and retrieve the part information, bend
  • an ODBC driver may be provided to permit each station
  • server module 32 or the network database module of database 30 may comprise a SQL
  • bend sequence and tool setup information may be sent from the station module of bending
  • This information may then be stored along with the other design and manufacturing
  • 3-D image representation of the part may be stored with the bend model data for the part.
  • the 2-D or 3-D image representation may be developed at design station 10 or another
  • the design station (or another appropriate location) and through the communications network
  • the 2-D or 3-D image may be developed at server module 32, by utilizing
  • FIGs. 3 and 4 are flow charts of the basic logic flow that may be performed by server module 32 and the station modules of each
  • VISUAL C++ may
  • Fig. 3 is a flow chart of the basic processes and operations performed by server
  • Fig. 3 illustrates the basic logic
  • Server module 32 may include a Windows based application with tool
  • step S.1 when a customer's order is received at the sheet metal manufacturing facility 38.
  • the customer's order will normally include the necessary product and design information
  • server module 32 may perform a search of previous job information stored in database 30, as
  • the job information stored in database 30 may be searched based on
  • search criteria For example, information may be searched based on a
  • predetermined reference or job number or a similar part search may be performed based on
  • step S.5 the results of the search of the database are analyzed to determine
  • information may be accessed from the database by an operator at the server module 32 or
  • translation table may be provided so that the file name ofthe previous job information may
  • server module 32 may access the job
  • a bending operator located at the station module of bending station 18 may also access the previous job information and utilize the manufacturing information, including the bending code data and tool setup information, to
  • step S.5 If, however, it is determined at step S.5 that the current customer's order is similar
  • step S.7 the previous job data located by
  • the search may be retrieved from database 30, and edited and modified by an operator at
  • An editing function may be provided to allow editing and modification
  • the amount of editing required will depend upon the amount of similarity
  • the amount of editing may be any amount of editing that exists between the previous job and the current job.
  • the revised job information may then be stored in database 30 at step S.9.
  • the revised job information may then be stored in database 30 at step S.9.
  • Menu and/or help screens may be provided by the server module 32 to assist the operator
  • an operator at server module 32 may create a new file by first entering the basic
  • the part information may comprise, for example, a
  • step S.15 data or search keys may also be entered at step S.15, or this data may be automatically
  • step S.15 logic flow proceeds so that the bend model data may be developed and
  • the development and entry of the bend model data may depend upon the original
  • the customer's order may include,
  • customer may also provide a 3-D, wire frame drawing of the part, with or without the
  • the bend model data may include both the unfolded (i.e., the first
  • the 2-D and 3-D models that are saved in the bend model may be any 2-D and 3-D models that are saved in the bend model.
  • Fig. 3 shows the general processes and operations performed when developing the
  • Server module 32 may, for example, interface
  • server module 32 may include a stand alone CAD/CAM system.
  • 2-D and 3-D drawings may be saved as DXF or IGES files and imported to server module 32.
  • step S.19 the 2-D, flat drawing that
  • part material e.g., width, height, depth
  • a folding algorithm or process may be utilized to develop a 3-D model (with no material thickness) based on the original 2-D
  • the drawing information may be entered at step S.27.
  • other bend may be entered at step S.27.
  • model data such as the overall dimensions of the part (e.g., width, height, depth), and part
  • material information may be entered at step S.27. Thereafter, an unfolding algorithm or
  • process may be executed at server module 32 in order to develop a 2-D model of the part
  • the 2-D and 3-D model representations of the part may be stored as part ofthe bend
  • S.25, S.31 and S.33 generally show the additional processing and operations that may be
  • step S.23 the drawing may be entered at or imported to server module 32.
  • bend model data such as the overall dimensions ofthe part (e.g., width, height,
  • step S.23 Thereafter, at step S.23.
  • the developed 3-D drawing may then be used to develop the 2-D
  • the drawing information may be entered at step S.31 for further processing
  • dimensions ofthe part e.g., width, height, depth
  • part material information may also be included.
  • server module 32 may prompt the operator or user to indicate the thickness in the drawing and to indicate which surfaces (e.g., the outside or inside) should be retained when
  • step S.33 logic flow will proceed to step S.29, where the revised 3-D model with no
  • customer's order may be transferred from server module 32 and stored in database 30 at step
  • the data stored in database 30 may include feature extraction or search data that may be used to extract feature extraction or search data.
  • search data may include data that is indicative of the basic or key features of the part
  • information entered at server module 32 may be sent directly to database 30 or transferred
  • Fig.4 is a flow chart of the basic processes and operations performed by each of the
  • Fig. 4 provides an example of basic
  • bending station 18 located at, for example, bending station 18.
  • server module 32
  • the station module may include a Windows

Abstract

An apparatus and method is provided for managing and distributing design and manufacturing information throughout a factory in order to facilitate the production of components, such as bent sheet metal components. In accordance with an aspect of the present invention, the management and distribution of critical design and manufacturing information is achieved by storing and distributing the design and manufacturing information associated with each job. By replacing the traditional paper job set-up or work sheet with, for example, an electronically stored job sheet that can be accessed instantaneously from any location in the factory, the present invention improves the overall efficiency of the factory. In addition, through the various aspects and features of the invention, the organization and accessibility of part information and stored expert knowledge is improved.

Description

APPARATUS AND METHOD FOR MANAGING AND DISTRIBUTING DESIGN AND MANUFACTURING INFORMATION THROUGHOUT A SHEET METAL PRODUCTION FACILITY
RELATED APPLICATION DATA
This application claims the benefit of U.S. Provisional Application No. 60/016,958,
filed May 6, 1996, entitled "Apparatus and Method for Managing and Distributing Design
and Manufacturing Information Throughout a Sheet Metal Production Facility," the
disclosure of which is expressly incoφorated herein by reference in its entirety.
COPYRIGHT NOTICE
A portion of the disclosure of this patent document contains material which is subject
to copyright protection. The copyright owner has no objection to the facsimile reproduction
by anyone of the patent disclosure, as it appears in the U.S. Patent and Trademark Office
patent files or records, but otherwise the copyright owner reserves all copyright rights
whatsoever.
BACKGROUND OF THE INVENTION
1. Field of the Invention
The present invention generally relates to the field of manufacturing and to the
production of components, such as sheet metal components. More particularly, the present invention relates to an apparatus and method for managing and distributing design and
manufacturing information throughout a factory in order to facilitate the production of bent sheet metal components.
2. Background Information
Traditionally, the production of bent sheet metal components at, for example, a
progressive sheet metal manufacturing facility, involves a series of production and
manufacturing stages. The first stage is a design stage during which a sheet metal part
design is developed based on a customer's specifications. A customer will typically place
an order for a particular sheet metal component to be produced at the facility. The
customer's order will usually include the necessary product and design information so that
the component may be manufactured by the factory. This information may include, for
example, the geometric dimensions of the part, the material required for the part (e.g., steel, stainless steel, or aluminum), special forming information, the batch size, the delivery date,
etc. The sheet metal part requested by the customer may be designed and produced for a
wide variety of applications. For example, the produced component may ultimately be used
as an outer casing for a computer, an electrical switchboard, an armrest in an airplane, or part
of a door panel for a car.
During the design stage, a sheet metal part design may be developed by the design
office of the manufacturing facility using an appropriate Computer- Aided Design (CAD)
system. Based on a customer's specifications, a 2-dimensional (2-D) model of the sheet
metal part may be developed by a programmer with the CAD system. Typically, a customer
will provided a blueprint containing one or more drawings of the component and the critical
geometric dimensions of the part. The blueprint may also indicate any special forming or
marking to be included in the part, as well as the location of holes or other types of openings
on the surface(s) of the sheet metal part. The design programmer will often use this blueprint to develop a 2-D model on the CAD system. The 2-D model may include a flat
view and one or more other perspective views of the sheet metal part, with bending line
and/or dimensional information.
Before actual bending of the sheet metal part takes place, the part must first be
punched and/or cut from initial stock material. Computer Numerical Control (CNC) or
Numerical Control (NC) systems are typically used to control and operate punch presses and
plasma or laser cutting machinery to process the stock material. In order to facilitate
processing of the stock material, a Computer-Aided Manufacturing (CAM) system or
CAD/CAM system can be used by a design programmer to generate control code based on
the 2-D model. The control code may comprise a part program that is imported to and
utilized by the punch press and/or cutting machinery to punch or cut the sheet metal
component from the stock material.
The next stage in the production process is a bending plan stage. During this stage, a bending plan is developed by a bending operator at the shop floor. The operator will
normally be provided with the blueprint or 2-D drawing of the component, along with one
or more samples of the cut or punched stock material. With these materials, the bending
operator will develop a bending plan which defines the tooling to be used and the sequence
of bends to be performed. The bending workstation may include CNC metal bending
machinery, such as a CNC press brake, that enables the operator to enter data and develop
a bending code or program based on the bending plan.
Once the bending plan is developed, the operator will set up the workstation for
initial testing of the bending sequence. During this testing stage, the punched or cut stock
material will be manually loaded into the press brake and the press brake will be operated
to execute the programmed sequence of bends on the workpiece. The operator will analyze - 4 - the final bent sheet metal part and inspect it for conformance with the customer's
specification. Based on the results of the initial runs of the press brake, the operator may
modify the bending sequence by editing the bending program. The operator may also
provide feedback to the design office so that the sheet metal part design can be appropriately
modified. Further testing will typically be conducted until the bent sheet metal component
is within the required design specifications.
One of the final stages in the production process is the bending stage. After the
bending plan has been developed and tested, the bending operator will set up the required
tooling at the bending station and operate the press brake based on the bending plan and the
stored bending program or code. Job scheduling is also performed in order to ensure that
the necessary amount of punched or cut stock material will be available on time at the
bending station, and so that other jobs will be completed by the requested delivery dates.
Job scheduling may be developed or modified by a shop floor foreman during the earlier
stages of the production process and/or concurrently throughout the entire process. After
the final bent sheet metal parts have been produced, the parts may then be assembled and
packaged for shipping to the customer.
The conventional production and manufacturing process described above suffers
from several drawbacks and disadvantages. For example, although the design and
manufacturing data for each customer's order is normally archived physically (e.g., by paper
in a file cabinet) or electronically (e.g., by storing on a disk or magnetic tape), such data are
normally stored separately and not easily retrievable. Further, in most factory settings, the
distribution of critical job information takes the form of a paper job or work sheet that is
distributed throughout the factory floor. As a result, data is often lost or damaged, and it is
difficult to search for both the design and manufacturing data relating to a previous or similar job. In addition, due to the inefficient manner in which the data is stored, valuable
time is lost in attempting to distribute the design and manufacturing information to the shop
floor and to other locations throughout the factory. Considerable manufacturing time is also
lost during the development of the sheet metal part design and bending plan, since the
development of the part design and bending plan is primarily performed by the design
programmer and bending operator, and relies heavily on the individual's knowledge, skill
and experience.
In recent years, there have been developments and attempts to improve the
conventional sheet metal manufacturing process and to improve the efficiency of the overall
process. For example, the use and development of 2-D and 3-dimensional (3-D) modeling
in commercially available CAD/CAM systems has facilitated and improved the production
process and modeling of bent sheet metal components. The design programmer and
operator can now utilize both the 2-D and 3-D representations to better understand the
geometry of the part and more efficiently develop a part design and bending code sequence.
The ability to store and transfer data electronically has also improved the flow of
information from the design office to locations on the shop floor. With the advancement of
computers and data communication networks, it is no longer necessary to search through a
cabinet or file of old paper tapes or magnetic disks.
Despite such advancements, there is still a need to improve the organization and flow
of design and manufacturing information throughout the factory environment. For example,
conventional manufacturing systems do not logically associate both critical design and
manufacturing information associated with each customer's order so that it may be easily
accessed and retrieved from any area in the factory. Previous systems also fail to provide
the ability to search previous job information based on various criteria, such as the features and attributes of the sheet metal component. The ability to search and retrieve previous job
information based on, for example, an identical or similar part search, would greatly enhance
the overall production process and reduce the required manufacturing time for future jobs.
Past attempts also fail to facilitate the development of the
sheet metal part design and bending plan by the design programmer and shop floor operator.
While the introduction of 2-D and 3-D modeling systems have enabled the designer to have
a better understanding of the shape and geometry of the part, such systems have not reduced
the burdens placed on the design programmer and shop floor operator. For example, such
systems have not enabled the design programmer to easily convert an existing 2-D CAD
model into a 3-D representation. In addition, while 2-D and/or 3-D drawings of the
component may be provided to the shop floor operator to assist in the development of the
bending plan, the operator must still determine and develop the tooling requirements and
bending sequence by hand and/or experimentation.
SUMMARY OF THE INVENTION
In view of the foregoing, the present invention, through one or more of its
various aspects, embodiments and/or specific features or sub-components thereof, is
provided to bring about one or more objects and advantages, such as those specifically noted
below.
A general object of the present invention is to provide an apparatus and method for
managing and distributing design and manufacturing information throughout a factory in
order to facilitate the production of components, such as bent sheet metal components.
A further object of the present invention is to provide an apparatus and method that
prevents the loss or destruction of critical job information, and that enhances the efficiency and organization of stored expert knowledge at, for example, a progressive sheet metal
production facility.
Another object of the invention is to provide an apparatus and method for logically
storing both the design and manufacturing information for each customer's order, so that it
may be easily accessed and retrieved from any area in the factory.
Yet another object of the present invention is to provide an apparatus and method
for managing and distributing design and manufacturing information, wherein the job data
is stored at a central database or file server in a logical fashion so that it may be easily
searched and retrieved from any location throughout the factory. The job data may provide not only the design and manufacturing information associated with the job, but also the
actual bend code for executing the required bending operations.
Still another object of the present invention is to provide an apparatus and method
for searching previous job information, including design and manufacturing information,
based on various search criteria. The search criteria may include, for example, the basic
features and attributes of the sheet metal component to be manufactured, so that previous
job information relating to an identical or similar part can be utilized to reduce the overall
manufacturing time of future jobs.
Another object of the present invention is to replace the traditional paper job or work
sheet, associated with each customer's order, with an electronic job sheet that can be
instantaneously accessed from any location in the factory. The electronic job sheet may be
displayed at any location and include critical design and manufacturing information,
including the 2-D and/or 3-D model view of the component, the tooling selection, the
optimum bending sequence, the required staging information, and the bar code or
identifϊcationnumber associated with the job. The electronic job sheet may also include an audio and or video portion recorded by a bending operator to indicate, for example, any
special instructions or procedures that may be helpful when running the same job or a
similar job again in the future.
Another object of the invention is to shorten the time required to analyze a part
drawing by providing 2-D and 3-D computerized views of the sheet metal part. Various
viewing modes may be provided, including a solid 3-D viewing mode, a 3-D wire frame
viewing mode, a 2-D flat screen viewing mode, and an orthographic viewing mode.
Different viewing functions may also be provided, including zooming, panning, rotating and
auto-dimensioning, to facilitate analysis of the sheet metal part.
A further object of the invention is to provide an apparatus and method that facilitates the development of the sheet metal part design and bending plan by the design
programmer and shop floor operator. For example, it is an object of the present invention
to enable the design programmer to easily develop a 3-D representation of the component
from an existing 2-D model. It is also another object of the invention to provide a graphical
user interface to shorten the time required to develop the bending plan and programmed
bending code.
The present invention, therefore, is directed to an apparatus and method for
developing a bend model of a part to be produced in an intelligent production facility,
wherein the part includes a plurality of faces and at least one bendline. The apparatus may
comprise a receiving system for receiving initial part information relating to the part,
including data relating to a representation of the part within a first predetermined coordinate
space. A face detecting system may also be provided for detecting, within the first
predetermined coordinate space, the faces of the part based on the initial part information.
In addition, the apparatus may include a bendline identification system for identifying at least one bendline of the part based on the detected faces, and a system for generating
additional part information, relating to the part and including data relating to a representation
of the part within a second predetermined coordinate space, by performing a predetermined
operation on each of the faces detected by the face detecting system. The predetermined
operation may be performed based upon at least the initial part information and at least one
bendline identified by the bendline identification system.
The first predetermined coordinate space may comprise a 2-D coordinate space and
the second predetermined coordinate space may comprise a 3-D coordinate space, wherein
the predetermined operation comprises a folding operation performed on the faces detected by the face detecting system. The folding operation may include rotating and translating
each of the faces detected by the face detecting system relative to at least one bendline
identified by the bendline identification system. In addition, the initial part information may
further comprise a bend angle amount relating to at least one bendline of the part, whereby the folding operation is performed based on the bend angle amount.
According to another aspect of the invention, the first predetermined coordinate
space may comprise a 3-D coordinate space and the second predetermined coordinate space may comprise a 2-D coordinate space, wherein the predetermined operation comprises an
unfolding operation performed on the faces detected by the face detecting system. The
unfolding operation may include rotating and translating each of the faces detected by the
face detecting system relative to at least one bendline identified by the bendline
identification system. In addition, the initial part information may further comprise a bend
angle amount relating to at least one bendline of the part, whereby the unfolding operation
is performed based on the bend angle amount.
The part to be produced may comprise a sheet metal part, and the data relating to a representation of the part within the first predetermined coordinate space may include
coordinate data and/or vector data. Further, the faces of the part may comprise the base
surface(s) of the part as well as the folded surfaces of the part.
According to another aspect of the invention, the initial part information may
comprise data relating to a representation of the part in a 3-D coordinate space, and the data
may include thickness data of the part in 3-D coordinate space.
The apparatus for developing a bend model may also include an auto-trimming and
cleanup system for performing an auto-trimming and cleanup operation on the data relating
to the initial part information to prepare the data for the face detecting system and the
bendline identification system. The data may comprise part entity data representing, at least, line entities and bendline entities of the part, and the auto-trimming and cleanup system may
further comprise a system for detecting intersection points of the entities and for selectively
breaking the entities at detected intersection points, and a system for assigning the resultant
broken entities to have a common endpoint based on the detected intersection points. The
auto-trimming and cleanup system may also comprise a system for detecting open
intersection areas between adjacent entities and for selectively connecting the adjacent
entities by assigning a common endpoint to the adjacent entities.
Open intersection areas may be detected, by the system for detecting open
intersection areas, when the endpoints of the adjacent entities are determined to be within
a predetermined distance from one another.
According to yet another feature of the invention, the data relating to the initial part
information may comprise part entity data representing, at least, line entities of the part, and
the face detecting system may be adapted to perform a loop and entity analysis of the part
based on the part entity data to detect the faces of the part. The loop and entity analysis may initially be performed on an outside boundary of the part and then performed on inner
boundaries and areas of the part. The face detecting system may generate an initial linked
list of entities when performing the loop and entity analysis on the outside boundary of the
part, such that the initial linked list of entities define an outward loop and boundary of the
part. The face detecting system may further generate an additional linked list of entities
when performing the loop and entity analysis on the inside boundaries and areas of the part,
such that the additional linked list of entities define inner loops and boundaries of the part.
In addition, the face detecting system may further comprise a system for generating a loop
tree based on the outward loop defined by the initial linked list of entities and the inner loops
defined by the additional linked list of entities. Further, the face detecting system may
detect the faces of the part based on the loop tree and the sequence of boundaries defined by
the initial linked list entities and the additional linked list of entities.
The bendline identification system of the invention may comprise a system for
analyzing the initial linked list of entities and the additional linked list of entities to
determine common line entities between the faces detected by the face detecting system.
Bendlines may be identified based on the detection of one of the faces having only one common line entity with another one of the faces. In addition, the bendline identification
system may apply predetermined heuristics to identify bendlines of the part when the system
for determining common line entities detects that there are more than one common line
entity between the faces. The heuristics may comprise identifying bendlines of the part such
that a minimum number of total bendlines are identified for the part. The heuristics may
also comprise identifying bendlines of the part, when one of the faces have more than one
common line entity with another one of the faces, based on the common line entity that has the longest length. According to another feature of the invention, a system for receiving a deduction
amount may be provided to receive a deduction amount related to the part. A system for
compensating for bend deduction, when performing the predetermined operation on the
faces, based on the deduction amount may also be provided. The system for compensating
for bend deduction may increase a dimensional length of the faces by one half of the
deduction amount on each side of the bendline of the part when performing a folding
operation. The system for compensating for bend deduction may also be adapted to decrease
a dimensional length of the faces by one half of the deduction amount on each side of the
bendline of the part when performing an unfolding operation.
The method for developing a bend model may comprise the following steps: receiving initial part information relating to the part, the initial part information including
data relating to a representation of the part within a first predetermined coordinate space;
detecting, within the first predetermined coordinate space, the faces of the part based on the
initial part information; identifying at least one bendline of the part based on the faces
detected by the detecting; and generating additional part information, including data relating
to a representation of the part within a second predetermined coordinate space, by
performing a predetermined operation on each of the faces detected by the detecting, the
operation being performed based upon the initial part information and at least one bendline
identified by the identifying.
The first predetermined coordinate space may comprise a 2-D coordinate space and
the second predetermined coordinate space may comprise a 3-D coordinate space. In
addition, the method may further comprise performing a folding operation on the faces
detected by the step of detecting. The folding operation may include rotating and translating
each of the faces relative to at least one bendline identified by the step of identifying. Further, the initial part information may comprise a bend angle amount relating to at least
one bendline of the part, whereby the folding operation is performed based on the bend angle
amount.
According to another feature of the invention, the first predetermined coordinate
space may comprise a 3-D coordinate space and the second predetermined coordinate space
may comprise a 2-D coordinate space. The method may also further comprise performing
an unfolding operation on the faces detected by the step of detecting. The unfolding
operation may include rotating and translating each of the faces relative to at least one
bendline identified by the step of identifying. Further, the initial part information may
comprise a bend angle amount relating to at least one bendline of the part, whereby the
unfolding operation is performed based on the bend angle amount.
The method may also comprise performing an auto-trimming and cleanup operation
on the data of the initial part information before detecting the faces and identifying the at
least one bendline. The data of the initial part information may comprise part entity data
representing, at least, line entities of the part, and the step of detecting of the faces may
comprise performing a loop and entity analysis of the part based on the part entity data to
detect the faces of the part. The loop and entity analysis may initially performed on an
outside boundary of the part and then performed on inner boundaries and areas of the part.
In addition, according to the invention, the step of identifying may further comprise
applying predetermined heuristics to identify bendlines of the part when more than one
common edge between the faces is detected. The heuristics may comprise identifying
bendlines of the part such that a minimum number of total bendlines are identified for the
part. The heuristics may also comprise identifying bendlines of the part, when one of the
faces have more than one common line entity with another one of the faces, based on the common line entity that has the longest length.
The present invention also encompasses a system for developing a bend model of a
part to be produced in a production facility, wherein the part includes a plurality of faces and
at least one bendline. The system comprises means for receiving initial part information
relating to the part, wherein the initial part information including data relating to a
representation of the part within a first predetermined coordinate space. Detecting means
may also be provided for detecting, within the first predetermined coordinate space, the
faces of the part based on the initial part information. The system may also include means
for identifying at least one bendline of the part based on the faces detected by the face
detecting means, and means for generating additional part information, including data
relating to a representation of the part within a second predetermined coordinate space, by
performing a predetermined operation on the faces detected by the detecting means. The
predetermined operation may be performed based on, at least in part, the bendline identified
by the bendline determining means of the system.
According to another aspect of the invention, a system and method is provided for
developing a bend model of a part to be produced in an intelligent production facility. The
system may comprise a receiving system for receiving initial part information relating to the
part, wherein the initial part information comprises respective representations of a plurality
of views the part in 2-D coordinate space, and each of the representations include part
thickness representations of the part. A cleanup operation system may also be provided to
perform a 2-D cleanup operation on the initial part information to eliminate any extraneous
information and to identify each of the representations. The system may also include a part
thickness elimination system for selectively eliminating the part thickness representations in each of the identified representations to provide modified representations of the views of the part in 2-D coordinate space with no thickness, and a system for developing a
representation of the part in 3-D coordinate space based on the modified representations of
the part in 2-D coordinate space with no thickness.
The initial part information may comprise part entity data representing, at least, line
entities of the part, and the cleanup operation system may include a break and trimming
system for detecting intersection points of the entities and for selectively breaking the
entities at detected intersection points. Further, the break and trimming system may assign
the resultant broken entities to have a common endpoint based on the detected intersection
points. The break and trimming system may further comprise a system for detecting open
intersection areas between adjacent entities and for selectively connecting the adjacent
entities by assigning a common endpoint to the adjacent entities.
Open intersection areas may be detected, by the system for detecting open intersection areas,
when the endpoints of the adjacent entities are determined to be within a predetermined
distance from one another.
In accordance with another aspect of the invention, the cleanup operation system
may comprise a system for developing a connectivity graph structure based on the initial
part information, such that the cleanup operation system eliminates extraneous information
based on the connectivity graph structure. The extraneous information that is eliminated
may comprise unconnected line entities, wherein the unconnected line entities relating to,
at least, dimension lines.
The initial part information may also comprise key words for identifying part entity
data and extraneous information relating to text. The cleanup operation system may
eliminate the extraneous information relating to text based on the key words included in the initial part information. According to yet another feature of the invention, the cleanup operation system may
comprise a system for detecting, based on the initial part information, the representations of
the top view, the front view, and the right side view of the part. As disclosed herein, the
plurality of views of the part may comprise a top view, a front view, and a right side view
of the part in 2-D coordinate space. In addition, the developing system may include a
system for performing a projection operation to develop the representation of the part in 3-D
coordinate space based on the representations of the part in 2-D coordinate space. The
projection operation may comprise detecting the relative depths of each of the plurality of
views and projecting each of the plurality of views into 3-D coordinate space.
The method for developing a bend model may comprise the steps of: receiving initial
part information relating to the part, the initial part information comprising respective
representations of a plurality of views the part in 2-D coordinate space, each of the
representations including part thickness representations of the part; performing a 2-D
cleanup operation on the initial part information to eliminate extraneous information and to
identify each of the representations;selectivelyeliminatingthe part thickness representations
in each of the identified representations to provide modified representations of the views of
the part in 2-D coordinate space with no thickness; and developing a representation of the
part in 3-D coordinate space based on the modified representations of the part in 2-D
coordinate space with no thickness.
The initial part information may comprise part entity data representing, at least, line
entities of the part, and the step of performing may comprise detecting intersection points
of the entities and selectively breaking the entities at detected intersection points, with the
resultant broken entities being assigned to have a common endpoint based on the detected
intersection points. The step of performing may also comprise detecting open intersection areas between adjacent entities and selectively connecting the adjacent entities by assigning
a common endpoint to the adjacent entities. Open intersection areas may be detected when
the endpoints of the adjacent entities are within a predetermined distance from one another.
The method may also comprise the steps of developing a connectivity graph structure
based on the initial part information and eliminating extraneous information from the initial
part information based on the connectivity graph structure. The extraneous information may
comprise unconnected line entities, the unconnected line entities relating to. at least, dimension lines.
In addition, the initial part information may comprise key words for identifying part entity
data and extraneous information relating to text, wherein the step of performing includes the
step of eliminating the extraneous information relating to text based on the key words.
According to another feature of the invention, the step of selectively eliminating the
part thickness may comprise prompting a user to identify the part thickness representations
to be eliminated in each of the plurality of views and to identify a dimension of the part to
be retained in each of the plurality of views. The dimension of the part may comprise one
of an outside dimension or an inside dimension of the part. Further, the step of developing
may comprise performing a projection operation to develop the representation of the part in
3-D coordinate space based on the modified representations of the part in 2-D coordinate
space. The projection operation may include detecting the relative depths of each of the
plurality of views and projecting each of the plurality of views into 3-D coordinate space.
Further features and/or variations may be provided in addition to those noted above.
For example, the invention may be directed to various combinations and subcombinations
of the above-described features and/or combinations and subcombinations of several further features noted below in the detailed description. The above-listed and other objects, features and advantages of the present invention
will more be more fully set forth hereinafter.
BRIEF DESCRIPTION OF THE DRAWINGS
The present invention is further described in the detailed description which follows,
by reference to the noted plurality of drawings by way of non-limiting examples of preferred
embodiments of the present invention, in which like reference numerals represent similar
parts throughout the illustrations, and wherein:
Fig. IA is a block diagram illustration of a progressive sheet metal manufacturing
facility constructed according to an embodiment of the present invention;
Fig. IB is a block diagram illustration of a progressive sheet metal manufacturing
facility constructed according to another embodiment of the present invention;
Fig. 2 illustrates the respective data flow between the server module, database and
station modules, in accordance with an aspect of the present invention;
Fig. 3 is a flow chart of the general processes and operations that may be performed
by the server module, according to another aspect of the invention;
Fig.4 is a representative flow chart of the basic processes and operations that may
be performed by each of the station modules, in accordance with the teachings of the present invention;
Figs. 5 A and 5B are flowcharts that illustrate the logic flow of a similar part search
algorithm or process, according to an aspect of the present invention;
Figs. 6A, 6B, 6C, 6D, 6E, 6F and 6G illustrate, in accordance with an aspect of the
invention, a feature extraction operation for a four bend box with touched corners and for
a four bend box with open corners;
Figs. 7A, 7B and 7C illustrate, in accordance with another aspect of the present invention, a feature relation operation and process for identifying search keys for a part
having a four bend box, a bridge and another four bend box; Fig. 8 is a flow chart that illustrates the logic flow of the processes and operations
that may be performed to develop a 3-D model from a 2-D, single view drawing using a
folding algorithm;
Figs. 9A, 9B, 9C, 9D and 9E illustrate examples of an auto-trimming function and
cleanup function that may be performed to prepare a drawing for a face detection process;
Figs. 10A, 10B, IOC, 10D, 10E, 10F, 10G, and 10H illustrate the various processes
and operations that may be performed in a face detection process, in accordance with an
aspect of the present invention;
Figs. 1 IA and 1 IB illustrate the development of a final bend graph data structure
from the execution of a face detection process and bend line detection operation, according
to an aspect of the present invention;
Fig. 12 is a flow chart of the basic logic flow for developing a 2-D model based on
an original 3-D drawing (with no thickness) using an unfolding algorithm and other
processes, according to the teachings of the invention;
Fig. 13 is a flow chart of the basic logic flow for developing a 3-D model based on
an original 2-D, three view drawing using a 2-D clean-up operation, in accordance with an
aspect of the present invention;
Fig. 14A is a flow chart, according to an aspect of the invention, of the basic logic
flow of the processes and operations for performing a 2-D clean-up operation on a 2-D, three
view drawing;
Figs. 14B and 14C illustrate views and aspects of an exemplary 2-D, three view
drawing that may be processed by the 2-D clean-up operation of the present invention;
Fig. 14D illustrates a rotated view feature of the 2-D clean-up operation of the
present invention; Figs. 14E illustrates, in accordance with an aspect of the present invention, a
canonical form relating to the 2-D clean-up operation of the present invention;
Figs. 15 A and 15B illustrate an example of a 2-D, three view drawing with thickness
and a simplified 2-D, three view drawing model with no thickness that may be developed
using an eliminate thickness procedure, according to the teachings of the present invention;
Fig. 15C is an illustration of a cross thickness line and thickness arc of an exemplary
part, according to an aspect of the invention;
Fig. 16 is a flow chart of the logic flow of the various processes and operations that
may be implemented to develop a 3-D model with no thickness from a 3-D drawing with
thickness, in accordance with an aspect of the present invention;
Fig. 17 illustrates an exemplary data structure and access algorithm of the bend
model that may be utilized when implementing the present invention through, for example,
object oriented programming techniques;
Fig. 18 illustrates a block diagram of the structure of the bend model viewer, in
accordance with another aspect of the present invention;
Fig. 19 illustrates an exemplary solid view window display that may be provided as
output to a display screen;
Fig. 20 illustrates an exemplary wire frame view window display that may be
provided as output to a display screen;
Fig. 21 illustrates a 2-D flat screen image window display that may be provided as
output to a display screen;
Fig. 22 illustrates an orthographic view screen image that may be provided as output to a display screen;
Fig. 23 illustrates an example of the various dimension items that may be displayed in an automatic dimension mode of the present invention;
Figs. 24A, 24B and 24C illustrate a manner in which the flange length may be
defined for various different parts, according to an aspect of the invention;
Figs. 25A and 25B illustrate, in accordance with another aspect of the present
invention, adding an auxiliary flange length for two different types of parts;
Figs. 26A, 26B and 26C illustrate a manner in which the flange length may be
indicated for various parts that are displayed with thickness, in accordance with yet another
aspect of the invention;
Figs. 27A and 27B illustrate manners in which the flange length of parts with acute bend angles may displayed, in accordance with a tangent dimension method and an
intersection dimension method of the invention;
Fig. 28 is a flow chart of the logic flow of the processes and operations that may be
performed to develop a bending plan through the use of a graphical user interface, in
accordance with another aspect of the present invention;
Fig. 29A illustrates an example of a bend sequence input screen image that may be
displayed to a bending operator for developing a bending sequence;
Figs. 29B and 29C illustrates examples of selection a bend sequence and modifying
the insertion direction, in accordance with another aspect of the present invention;
Figs.29D and 29E illustrate further examples of a bend sequence input screen image
and a related screen display;
Fig. 30 illustrates, in accordance with an aspect of the present invention, a drag and
drop editing feature that may be provided to facilitate a bending operator in modifying and
editing a proposed bend sequence;
Fig. 31 illustrates an example of the various display menus and data tables that may be graphically displayed to aid a bending operator in selecting tooling;
Fig. 32 illustrates an exemplary tool set-up window that may be displayed to a
bending operator to facilitate the set-up of tooling in a proposed bending plan;
Fig. 33 A illustrates an example of a 3-D solid view window display with audio and
visual information attached through the use of pasted icons;
Fig. 33B illustrates another example of a display window that may be incoφorated
with icons for retrieving stored audio and video information, in accordance with an aspect
of the invention;
Fig. 34 illustrates an example of an image editing window that may be implemented
in accordance with the teachings of the present invention;
Figs. 35 A and 35B illustrate examples of a collision check function of the present
invention that may be implemented through a graphical user interface;
Figs.36A and 36B illustratea manipulation system of the invention for manipulating
the rotation and display of 3-D geometrical shapes by using, for example, a joystick;
Fig. 37 illustrates a manipulation system of the invention for manipulating the
zooming and display of 3-D geometrical shapes by using, for example, a joystick and zoom button;
Fig. 38 illustrates a manipulation system of the invention for manipulating the
panning and display of 3-D geometrical shapes by using, for example, a joystick and pan button;
Fig. 39 is an exemplary flow chart of the processes and operations that may be
performed in order to implement the 3-D navigation and manipulation system of the present
invention;
Fig.40 illustrates an example of mapping joystick movements to cursor movements, in accordance with an aspect of the invention;
Fig. 41 is an exemplary flow chart of the processes and operations that may be
performed to dynamically calculate the rotation axis of the rendered part;
Fig.42 illustrates an example of a main menu window display that may be provided
and displayed at, for example, a station module;
Fig. 43 illustrates an exemplary part information window display that may be
provided to permit a user to enter and modify part information;
Fig. 44 illustrates an exemplary bendline information window display that may be
provided to permit a user to enter and modify bendline information;
Fig. 45 illustrates an exemplary bend sequence window display of the present invention for viewing the intermediate bend stages of a sheet metal part;
Fig.46 illustrates an exemplary bend simulation window display of the invention for
simulating the intermediate bend stages of a sheet metal part;
Fig. 47 is an exemplary menu screen diagram and structure of the present invention
that may be provided and displayed to users for 2-D to 3-D conversions; and
Fig. 48 is an exemplary menu screen diagram and structure for a 2-D clean-up
operation of the present invention.
Fig. 49A illustrates an example of a 3-D representation of a part before one sided
open lines are removed, and Fig. 49B illustrates the part after the one sided open lines have
been removed from the 3-D representation, according to a 3-D clean-up process of the
invention that may be used when developing a 3-D model of a part from a 2-D, three view
drawing of the part;
Fig. 50A illustrates an exemplary 3-D representation of a part before the bendlines
have been identified, and Fig. 50B illustrates the part after the mold lines have been added, according to a 3-D clean-up process of the invention; and
Fig. 51 A illustrates an exemplary section of a part before cleaning the bendlines and
trimming the faces, and Fig. 5 IB shows the section of the part after cleaning and trimming
has been performed, according to a 3-D clean-up process of the invention.
BRIEF DESCRIPTION OF THE APPENDICES
In order to further facilitate the detailed description of the present invention,
reference is made to the noted plurality of appendices by way of non-limiting examples of
preferred embodiments of the present invention, in which sample source code and comments
are provided with respect to the various features, operations and functions of the invention,
and wherein:
Appendix A is an exemplary source code for executing a feature extraction operation
of the present invention when performing, for example, a similar part search;
Appendix B is an exemplary source code for effectuatinga similarity index operation
when performing, for example, a similar parts search of the invention;
Appendix C is an exemplary source code for performing a bendline detection
operation of the invention;
Appendix D is an exemplary source code for implementing a 2-D cleanup operation
of the present invention, which may be utilized when developing a 3-D model of a sheet
metal part based on an original 2-D, three view drawing;
Appendix E is an exemplary source code for implementing the various view modes
and functions of a bend model viewer of the present invention:
Appendices F, G, H and I are exemplary source code and comments relating to
executing and performing an auto dimensioning feature of the present invention;
Appendix J is an exemplary source code for implementing a part and entity visibility function of the bend model viewer of the invention;
Appendix K includes general comments relating to the implementation of the bend
model and the organization of the part structure, according to the various teachings of the
present invention; and
Appendix L includes exemplary source code for implementing a 3-D manipulation
and navigation system with dynamic calculation of the rotation axis of the rendered part.
DETAILED DESCRIPTION OF THE INVENTION
According to an aspect of the present invention, an apparatus and method are
provided for managing and distributing design and manufacturing information throughout
a factory, and for facilitating the production of components within the factory. The features of the present invention may be used in a wide variety of factory environments and settings
and, more particularly, the invention may be implemented in factory environments wherein
a series of production and manufacturing stages are effectuated at different locations. By
way of non-limiting embodiments and examples, the present invention will now be
described with reference to the production of bent sheet metal components at, for example,
a progressive sheet metal manufacturing facility.
Referring to Fig. 1 A, a progressive sheet metal manufacturing facility 38 is generally
illustrated in block diagram form, according to an embodiment of the present invention. As
shown in Fig. IA, the sheet metal manufacturing facility or factory 38 may include a
plurality of locations 10, 12, 14...20 that are dispersed throughout the factory. These
locations may comprise a design office 10, an assembly station 12, a shipping station 14, a
punching station 16, a bending station 18, and a welding station 20. Although the sheet
metal factory 38 in Fig. IA is depicted as having only six discrete locations, the factory may
of course include more than six discrete locations and may also include more than one location for each type of office or station illustrated in Fig. 1 A. For example, depending on
the size of and production capacity requirements for the facility 38, more than one punching
station 16, bending station 18, and/or welding station 20 may be provided. In addition, the
factory 38 may include more than one design office 10, assembly station 12 or shipping
station 14, and may also include other types of locations for facilitating the production and
manufacturing of components, such as bent sheet metal components.
Each of the locations 10, 12, 14...20 within the factory 38 may be adapted and
include equipment to execute one or more of the discrete production and manufacturing
stages or processes associated with the production and manufacturing of the components.
For example, the design office 10 may include an appropriate CAD/CAM system, to
facilitate the development of the sheet metal part design based on a customer's specification
The CAD/CAM system may comprise one or more personal computers, a display unit, a printer, and commercially available CAD/CAM software. By way of a non-limiting
example, the CAD/CAM system of the design office 10 may include AUTOCAD or
CADKE Y, or an Amada AP40 or AP60 CAD/CAM system available from Amada America,
Inc. (previously operating under the coφorate name of U.S. Amada Ltd.), Buena Park, California. In addition, other commercially available CAD systems may be used, such as
VELLUM, which is a Windows based CAD system available from Ashlar Incoφorated.
With the CAD/CAM software, the design programmer may develop a 2-D model and/or 3-D
model of the sheet metal part based on the drawings and data provided in the customer's
order. The design programmer may also generate control code based on the sheet metal part
design, in order to generate a part program for controlling, for example, CNC punch presses
and/or cutting machinery to punch or cut the sheet metal component from stock material.
Punching station 16 and bending station 18 may, each be provided with any combination of CNC and/or NC based machine tools. For example, punching station 16
may include one or more CNC and/or NC punch presses, such as COMA series and/or
PEGA series Amada turret punch presses or other commercially available CNC and/or NC
punch presses, and bending station 18 may include one or more CNC and/or NC press
brakes, such as RG series Amada press brakes or other commercially available multiple-axis,
gauging press brakes. Further, welding station 20 may be provided with appropriate welding
machinery in order to effectuate any required welding to the sheet metal component.
Punching station 16, bending station 18 and welding station 20 may be located at various
areas on the factory floor of the facility 38 and include machinery that is manually operated
by skilled operators (e.g., punch press operators, bending operators, etc.). Fully automated or robot assisted machinery, such as the Amada CELLROBO MINI and the Amada
PROMECAM, may also be provided at these locations. The required punching and bending
operations, and any necessary welding operations, may be performed at these stations during
the production process. As further shown in Fig. 1 A, the progressive sheet metal facility 38 may also include
assembly station 12 and shipping station 14. Assembly station 12 and shipping station 14
may include the necessary packaging, routing and/or transportation equipment to facilitate
the assembly and shipping of the manufactured components to the customer. The assembly
and shipping of the components may be performed or controlled manually by factory
personnel and also may be machine automated and/or machine assisted. In addition,
assembly station 12 and shipping station 14 may be physically located near the factory floor
(e.g., in close proximity to punching station 16, bending station 18 and/or welding station
20) or within a separate facility or area of the sheet metal factory 38.
In accordance with an aspect of the present invention, the management and distribution of critical design and manufacturing information is achieved by electronically
storing and distributing the design and manufacturing information. By replacing or at least
supplementing the traditional paper job set-up or work sheet with an electronic job sheet that
can be accessed instantaneously from any location in the factory, the present invention
improves the overall efficiency of the factory. In addition, through the various aspects and
features of the invention, the organization and accessibility of stored design and
manufacturing information is improved. Further, the ability to access and retrieve previous
job information relating to similar or identical sheet metal parts is enabled through the
various features of the invention. To this end, the various aspects of the present invention may be implemented and
effectuated by providing a communications network 26 that interconnects a server module
32 and a database 30 to each of the plurality of locations 10. 12, 14...20 within the sheet
metal facility 38. As further discussed below, each of the locations 10, 12, 12...20 may
include station modules that interface with communications network 26 and database 30.
Figs. IA, IB and 2 illustrate non-limiting examples of these features and implementation
of the invention.
As shown in Figs. IA and IB, communications network 26 may interconnect each
of the various locations 10, 12, 14...20 of the facility 38 with server module 32 and database
30. Communications network 26 may comprise any network capable of transmitting data
and information to and from the locations 10, 12, 14...20 and the server module 32 and
database 30. Such transmission may be achieved electronically, optically, by RF
transmission or by infrared transmission. By way of non-limiting example, communications
network 26 may be implemented by a Local Area Network (LAN), Ethernet or an equivalent
network structure. As further discussed below, each of the locations 10, 12, 14...20 may also include station modules having network terminating equipment (such as a computer,
minicomputeror workstation) and/or peripheral devices (such as a display monitor or screen,
printers, CD-ROMs, and/or modems) to transmit and receive information over
communications network 26. The network terminating equipment and peripheral devices
may include hardware and appropriate software or programmed logic for interfacing with
communicationsnetwork 26 and for providing the various features and aspects of the present
invention, as more fully discussed below. If a computer is provided at the factory location,
the computer may be a stand-alone, personal computer or a general puφose computer that
is part of an interface device of the equipment or machinery provided at the location. For
example, the computer may be an IBM compatible personal computer or may be a computer that is part of an interface/control system of the machinery, such as an Amada AMNC
system.
Server module 32 and database 30 are also connected to communications network
26. Server module 32 may comprise network terminating equipment, such as a personal
computer, minicomputeror mainframe, with suitable hardware and software for interfacing
with communicationsnetwork 26. Server module 32 may also include software or firmware
for implementing the various features of the invention, such as those described in greater
detail hereinafter. Further, according to an aspect of the present invention, server module
32 may also include database 30 for storing the design and manufacturing information
associated with each customer's order. Database 30 may be implemented by any
commercial available database with sufficient memory capacity for storing the design and
manufacturing information of the factory's customers and storing other data, tables and/or
programs. For example, database 30 may comprise a SCSI memory disk with 4 GB or more
of available memory space. The design and manufacturing information that is stored in database 30 may be accessed and distributed to the various locations 10, 12, 14...20 within
the sheet metal facility 38 via communications network 26. Various data formats, such as
Structured Query Language (SQL), may be used for accessing and storing data to database
30. In addition, information that is stored in database 30 may be backed-up and stored on
a wide variety of storage medium, such as magnetic tape, optical disks or floppy disks.
Server module 32 and database 30 may be connected to communications network 26 at a
separate area or location within the factory 38 (see, e.g., Fig. 1 A), or at a location that is
within or in close proximity to one of the predefined stations (e.g., within design office 10).
Although the embodiment of Fig. 1 A depicts database 30 as being part of server module 32
and interfacing with communications network 26 via the server module, database 30 may of course be physically located separately from server module 32 and connected to
communicationsnetwork 26 via a network database module 34, such as that shown in Fig.
IB.
By way of a non-limiting example, and in accordance with a preferred embodiment
of the present invention, server module 32 and each of the locations 10, 12, 14...20 may
comprise a personal computer, such as an IBM compatible computer with a 100-200 MHz
central processor unit (CPU), including a Pentium or an equivalent microprocessor, at least
32 MB of memory and a high resolution display screen, such as any commercially available
SVGA monitor with 800 x 600 resolution. Server module 32 and locations 10, 12, 14,...20
may also include a joystick or mouse device and a Sound Blaster or compatible sound and
game port adapter card for interfacing and controlling the display of information. Operating
system software may also be provided to support communications. For example, server
module 32 may be provided with Microsoft Windows New Technology (NT) or Windows
95 operating system software (both of which are available from Microsoft Coφoration, Redmond, WA), and each of the locations 10, 12, 14...20 may include Microsoft Windows
95 operating system software. In addition, server module 32 and locations 10, 12, 14...20
may be adapted to support multiple languages (such as English, Japanese, etc.) and full
support for an Object Linking and Embedding (OLE) server, such as an OLE2 server, may be provided.
Various database languages and management systems may also be used for creating,
maintaining and viewing information stored in database 30. A database language such as
Structured Query Language (SQL) may be used for defining, manipulating and controlling
data in database 30. For example, SQL Server (which is a retail product available from
Microsoft Coφoration) may be utilized to implement the present invention. In addition, the
invention may be provided with an Open Database Connectivity (ODBC) compatible driver
to facilitateaccessofinformationfrom database 30 over communicationsnetwork 26. More
information concerning OBDC may be found, for example, in the Microsoft Open Database
Connectivity Software Development Kit Programmers Reference manual.
Fig. 1 B illustrates, in block diagram form, a progressive sheet metal manufacturing
facility constructed according to another embodiment of the present invention. In the
embodiment of Fig. IB. the database 30 and server module 32 are provided separately, with
the database 30 being connected to communications network 26 via a network database
module 34. As discussed above, the present invention is not limited to this arrangement and
the database 30 and server module 32 may be provided together (as shown, e.g., in Fig. 1 A),
with the functionality of the network database module 34 for providing access to the
database being incoφorated in the server module. The embodiment of Fig. IB also
illustrates an example of the station module 36 that may be provided at each of the various
locations 10, 12, 14...20 throughout the sheet metal manufacturing facility 38. For puφoses of illustration, an exemplary station module 36 that may be located at bending station 18 is
provided in Fig. IB. Although not depicted in the example of Fig. IB, similar station
modules 36 may also be provided at the other locations within the facility 38.
As shown in Fig. 1 B, each of the modules (i.e., server module 32, network database
module 34, and station module 36) may be connected to communications network 26 via a
network interface card or port 42. The network interface card 26 may be vendor specific and
be selected based on the type of communications network that is selected. Each of the
modules 32, 34 and 36 may also include network software or programmed logic for
interfacing with the communicationsnetwork 26. The communicationsnetwork 26 may be
an Ethernet with any of a number of commercially available cable types, such as 10 Base/T
(twisted pair), 10 Base/2 (coax), or 10 Base/5 (thick cable), with the cable type being
selected based on the size of facility 38 and the amount or length of the cable required.
In Fig. IB, server module 32 may comprise a personal computer 40 with display
monitor or CRT 44 and input/output devices 46. which may include a keyboard, mouse
and/or joystick. The network interface card 42 may be plugged into an available expansion
slot or port of the personal computer 40. In addition, personal computer 40 may comprise
an IBM compatible computer with 100-200 Mhz operating speed and a Pentium or Pentium
Pro microprocessor. Personal computer 40 may also include, for example, 32 MB or more
of available main memory and 1.2 GB or more of available random access memory (RAM).
Display 44 may include a high resolution display screen, such as any commercially available
SVGA monitor with, for example, 800 x 600 resolution. To support the various graphics
and information that may be displayed on display 44, personal computer 40 may also
include any commercially available graphics card such as a PCI graphics card. Further,
computer 40 may include a Sound Blaster or compatible sound and game port adapter card and input output devices 46 may include a keyboard, joystick and/or mouse device.
In order to implement the various features of the invention, server module 32 may
be configured with software and various software packages. For example, server module
32 may be provided with operating system software, such as Microsoft Windows NT
(workstation version) or Windows 95. Further, in order to provide the server module
specific functionality and features of the invention (see, e.g., Fig. 3 ), server module 32 may
include software or programmed logic implemented routines. As discussed in greater detail
below, these routines may be developed using a high level programming language, such as
C++, and object oriented programming techniques. Server module 32 may also include or
interface with CAD or CAD/CAM software, such as VELLUM or Amada AP40 or AP60
software, to enter and/or develop original 2-D and 3-D drawings based on a customer's
specifications. For this reason, server module may be located in the design office 10 of the
manufacturing facility 38. In order to access data from database 30, server module 32 may
also include an OBDC driver, such as Microsoft ODBC driver, and may use SQL as a
standard for accessing data. An OLE server, such as OLE2 server, may also be provided to
link the data.
In the embodiment of Fig. IB, database 30 is provided separate from server module
32 and is connected to communications network 26 via network database module 34. As
indicated above, database 30 may comprise a SCSI disk with appropriate memory space
(e.g., 1 -4 GB), which may be selected based on the size of the factory 38 and the amount of
part information to be stored in the database. Network database module 34 may include a
personal computer 40, such as an IBM compatible computer with a Pentium microprocessor,
and an expansion slot fitted with network interface card 42 for interfacing with
communications network 26. Database 30 may be connected to personal computer 40 via a data bus and personal computer 40 may include standard display and input/output devices
(not shown in Fig. IB), such as a display monitor or CRT and a keyboard.
In order to facilitate access to database 30 based on SQL, personal computer 40 of
network database module 34 may be configured with a commercially available SQL server,
such as a Microsoft SQL server or Oracle SQL server. An OLE server, such as OLE2
server, may also be provided to link the data. Personal computer 40 may also be configured
with various operating software, such as DOS and Microsoft Windows NT (server version).
The embodiment of Fig. IB also includes an exemplary implementation of one
station module 36. In this embodiment, the station module 36 is implemented at bending
station 18. As shown in Fig. 1 B, the station module 36 may include similar hardware to that of the server module 32. That is, each station module (e.g., at the other stations shown in
Fig. 1 A) may comprise a computer 48 with display monitor or CRT 44 and input output
devices 46, which may include a joystick or mouse. The network interface card 42 may be
plugged into an available expansion slot or port of the computer 40. As discussed above,
the computer of the station module 36 may be a stand-alone, personal computer or a general
puφose computer that is part of an interface device of the equipment or machinery provided
at the location. For example, computer 48 may comprise a free-standing, personal computer
such as an IBM compatible computer with 100-200 Mhz operating speed and a Pentium or
Pentium Pro microprocessor, or computer 48 may be a computer that is part of or built into
an interface/control system of the machinery, such as an Amada AMNC system. Computer
48 may also include, for example, 32 MB or more of available main memory and 1.2 GB
or more of available random access memory (RAM). Display 44 may include a high
resolution display screen, such as any commercially available SVGA monitor with, for
example, 800 x 600 resolution. To support the various graphics and information that may be displayed on display 44, computer 48 may also include any commercially available
graphics card such as a PCI graphics card. Further, computer 48 may include a Sound
Blaster or compatible sound and game port adapter and to support, for example, a joystick
or mouse of the input/output devices 46.
In order to implement the various features of the invention, station module 36 may
also be configured with software and various software packages. For example, station
module 36 may be provided with operating system software, such as Microsoft Windows
95 or Windows NT (workstation version). Further, in order to provide the station module
specific functionality and features of the invention (see, e.g., Fig. 4 ), station module 36 may
include software or programmed logic implemented routines. As discussed in greater detail
below, these routines may be developed using a high level programming language, such as
C++, and object oriented programming techniques. In order to access and link data, station
module 36 may also include an OBDC driver, such as Microsoft ODBC driver, and an OLE
server, such as OLE2 server. Similar to server module 32, station module may use SQL as
a standard for accessing data from database 30.
If the station module 36 of bending station 18 is provided as a free-standing personal
computer, then software may be provided to
create bending code data (i.e., NC data) and to interface with the machinery 25 (e.g., a CNC
or NC controlled press brake). In the embodiment of Fig. IB, computer 36 is illustrated as
being implemented as a personal computer and is configured with software to interface with
bending machinery 25 via a standard RS-232-C wire interface. This interface may be
provided to permit the station module 36 to communicate with and send or receive bending
code data to the bending machinery 25 via the RS-232-C interface. The implementation of the interface is vendor specific and will depend on the data format and machine instruction set used for the bending machinery 25. All data that is sent from the station module 36 to
the bending machinery 25 should thus be formatted based on the machine instruction set that
is defined for the machinery. The computer 48 of station module 36 may also be provided
with any commercially available CNC or NC software for generating bending code data, in
order to simulate the functionality that is normally provided by a built-in computer of CNC
or NC systems (such as a Amada AMNC) for such machinery.
Fig. 2 illustrates an exemplary embodiment of the respective data flows between
server module 32, database 30 and the various locations of the sheet metal manufacturing
facility 38. For puφoses of illustration, and to better facilitate the description of the
respective data flow in the embodiment, server module 32 and database 30 (integrated with
network database module 34) are each shown in Fig. 2 as being separately and directly
connected to communications network 26, with the data flow between these elements being
carried out across the communicationsnetwork. Of course, as will be appreciated by those
skilled in the art, a wide variety of data flow arrangements may be provided between these elements; and, if database 30 is arranged to be directly connected to server module 32, then
the data and information can be directly transferred from the server module to the database
without use of communications network 26. In addition, for puφoses of facilitating the
description herein, the illustration of communications network 26 in Fig. 2 has been
simplified and only punching station 16 and bending station 18 are shown in the drawing.
Nonetheless, it will be appreciated that the data flow to and from locations 10, 12, 14...20
(as well as any other location or area that may be present in the factory) may be carried out
in a similar manner to that described for punching station 16 and bending station 18.
The design and manufacturing information associated with each customer's order may be organized and stored in database 30. When a customer's order is initially received, basic product and design information may be entered at server module 32 and then
transferred and stored to database 30. As discussed above, server module 32 may include
any suitable means for entering the data, such as a personal computer with a keyboard, etc.
If a personal computer is utilized at server module 32, software may be provided to generate
menu driven screens to facilitate the entry of the data by factory personnel. The data entry
program may be, for example, a Microsoft Windows based application with help and/or
menu screens, etc. By way of a non-limiting example, the data that is entered and/or
developed at server module 32 and transferred to database 30 may include part information,
bend model data, feature extraction data, and bend line information, as generally illustrated
in Fig. 2.
The part information may comprise, for example, a part or order reference number,
the customer's name, a brief description of the part, the batch size or quantity, and scheduled delivery date. The bend model data may include, for example, part geometry and
manufacturing data, such as the overall dimensions of the part (e.g., width, height, depth),
and part material information such as the material type (e.g., steel, stainless steel, or
aluminum), thickness and tensile strength. Further, feature extraction data may be manually
entered and/or automatically generated to identify the key features of the part and to
facilitate similar part searches and other searches of the database. The feature extraction
data may be stored in a separate data file in database 30, or may be stored with the bend
model data and other job information for each part. The feature extraction data may
comprise, for example, features of the part such as the number of surfaces or faces, the
number or types of bends present (e.g., a positive bend between two faces or a negative bend
between two faces), the relationships between the faces and or the number of holes or other types of openings in the part. As discussed more fully below, such data may be represented and organized in a feature based part matrix and/or a sequence of search keys (see, e.g., Figs.
5-7 below). Lastly, bend line information may be entered at server module 32 for storage
in database 30. The bend line information may comprise, for example, pertinent bend line
information for each bend in the part, including the bend angle, the bend length, the inside
radius (IR) of the bend, the amount of deduction, and the bend direction (e.g., front or back).
In order to transmit to and receive data from database 30 over communications
network 26, each of the locations 10, 12, 14...20 may comprise a station module (such as
station module 36 described above) that is connected to the communications network. In
Fig. 2, punching station 16 and bending station 18 are generally illustrated in block diagram
form with a station module. As discussed above, the station module may comprise, for
example, software or control logic and a stand-alone personal computer or a general puφose
computer that is part of the equipment or machinery provided at the location. For each
customer's order, the design and manufacturing information (including the part information,
bend line information, and bend model data) may be accessed and retrieved by entering, for example, a predetermined reference number or code. The reference number or code may be
entered manually (e.g., by keyboard or digital input pad) or by scanning a bar code with a
bar code reader or scanner provided at the station module. In addition, in accordance with
an aspect of the present invention, previous job data may be accessed and retrieved from
database 30 from any location 10, 12, 14...20 within the factory 38 by performing a similar
part search. As discussed more fully in the detailed description that follows, a similar part
search may be conducted based on the feature extraction data or search keys stored in
database 30 so that previous job information relating to identical or similar part(s) can be
retrieved and utilized to reduce the overall manufacturing time of future jobs.
The design and manufacturing information that is retrieved from database 30 may be used by the shop floor operators to develop and test the bending plan. For example, a
bending operator at bending station 18 may access and retrieve the part information, bend
line information and bend model data from database 30 in order to determine the necessary
tooling and the optimum bend sequence for the sheet metal part. In accordance with an
aspect of the present invention, an ODBC driver may be provided to permit each station
module to interface database 30 and display information stored in the database. In addition,
server module 32 or the network database module of database 30 may comprise a SQL
server to facilitate the access and retrieval of data stored in the database. Once the bending code has been programmed based on the final bending plan, the bending code along with the
bend sequence and tool setup information may be sent from the station module of bending
station 18 to database 30 over communications network 30, as generally shown in Fig. 2.
This information may then be stored along with the other design and manufacturing
information associated with that job.
Other information may also be stored in database 30. For example, the 2-D and/or
3-D image representation of the part may be stored with the bend model data for the part.
The 2-D or 3-D image representation may be developed at design station 10 or another
location with a CAD/CAM system and transferred to database 30 via the station module of
the design station (or another appropriate location) and through the communications network
26. Alternatively, the 2-D or 3-D image may be developed at server module 32, by utilizing
or interfacing with an appropriate CAD/CAM system or modeling software and performing
a series of functions or operations, as will be discussed more fully below.
Referring now to Figs.3 and 4, a detailed description of the processes and operations
that may be programmed and performed by server module 32 and the station modules of each of the locations 10, 12, 14...20 will be provided. Figs. 3 and 4 are flow charts of the basic logic flow that may be performed by server module 32 and the station modules of each
ofthe locations 10, 12, 14...20 withinthe sheet metal manufacturingfacility 38. While Fig.
4 is directed to the processes and operations that would typically be performed at, for
example, bending station 18, it will be appreciated that other processes and steps may be
performed depending upon the operations performed at each particular location within the
facility 38. The processes and operations discussed below may be implemented by software
and by using any one of a wide variety of programming languages and techniques. For
example, in accordance with an aspect ofthe present invention, the processes and operations
described below with reference to the accompanying drawings may be implemented by
using a high level programming language such as C++ and using object oriented
programming techniques. Further, by way of a non-limiting example, VISUAL C++ may
be utilized, which is a version of the C++ programming language written by Microsoft
Coφoration for Windows based applications.
Fig. 3 is a flow chart of the basic processes and operations performed by server
module 32, in accordance with an aspect ofthe invention. Fig. 3 illustrates the basic logic
flow of the processes and operations performed by the software or programmed logic of
server module 32. Server module 32 may include a Windows based application with tool
bar icons and help and/or menu screens to assist an operator or user in selecting and
executing the various processes and operations ofthe server module. The process begins
at step S.1 , when a customer's order is received at the sheet metal manufacturing facility 38.
The customer's order will normally include the necessary product and design information
so that the component may be manufactured by the factory 38. This information may
include, for example, the geometric dimensions ofthe part, the material required for the part, and other design information. Based on the information received from the customer, server module 32 may perform a search of previous job information stored in database 30, as
illustrated in step S.3. The job information stored in database 30 may be searched based on
a wide variety of search criteria. For example, information may be searched based on a
predetermined reference or job number or a similar part search may be performed based on
certain design features ofthe part, so that previous job information relating to an identical
or similar part can be retrieved and utilized for the current job. A more detailed description
of a similar parts search that may be utilized is provided below with reference to Figs. 5-7.
At step S.5, the results of the search of the database are analyzed to determine
whether the current customer's order relates to a new part, a part that is similar to a previous
job, or a repeat of a previous job. If an identical match is found (e.g., the same part or reference number is located) and the present customer's order is a complete repeat of a
previous job performed at the factory, then no further modifications to the job information
is necessary and the previous job information may be accessed from database 30 and used
to carry out the present customer's order, as shown at step S.1 1. The search of the database
may provide the part or reference number and or file name ofthe previous job so that the job
information may be accessed from the database by an operator at the server module 32 or
any of the station modules. If only the part or reference number is provided, then a
translation table may be provided so that the file name ofthe previous job information may
be determined and accessed based on the entry of the part reference or job number by an
operator. Thus, an operator at, for example, server module 32 may access the job
information and the 2-D and 3-D modeling information from database 30 to analyze the
geometry ofthe part and confirm that it is similar to that ofthe repeat order. If the order is
confirmed to be a repeat order, then a bending operator located at the station module of bending station 18 may also access the previous job information and utilize the manufacturing information, including the bending code data and tool setup information, to
bend and produce the part. The use of such stored expert knowledge thus enables repeat
orders to be manufactured more efficiently and without the need to reproduce previously
entered and developed job information.
If, however, it is determined at step S.5 that the current customer's order is similar
to a previous job or the same as a previous job but requires modification of, for example, the
job or reference number or batch size, etc., then at step S.7 the previous job data located by
the search may be retrieved from database 30, and edited and modified by an operator at
server module 32. An editing function may be provided to allow editing and modification
of previous job data to create new job data that may be stored in database 30 for the present
customer's order. The amount of editing required will depend upon the amount of similarity
that exists between the previous job and the current job. The amount of editing may
encompass simply modifying the reference or job number or batch size, and/or may involve
more extensive modifications such as editing the dimensions of the part and the defined
bend sequence. After the previous job information has been edited, the revised job information may then be stored in database 30 at step S.9. The revised job information may
be stored under a new reference or job number. In addition, various database management
functions (such as copy, delete, save, rename, etc.) may be provided to permit the previous
job information to be maintained in database 30 or to permit the previous job information
to be erased or overwritten upon entry of a special command.
If it is determined that there is no similar or identical match to the current job and,
thus, that the present customer's order relates to a new job, then logic flow proceeds to step
S.15, as shown in Fig. 3. Since, in this case, the current job relates to a new job it will be
necessary to independently develop and enter the design and manufacturing information. Menu and/or help screens may be provided by the server module 32 to assist the operator
in entering all of the necessary job information. In accordance with an aspect of the
invention, an operator at server module 32 may create a new file by first entering the basic
part information for the new job. The part information may comprise, for example, a
reference or job number, the customer's name, a brief description ofthe part, the required
batch size or quantity for the job, and the scheduled delivery date. The feature extraction
data or search keys may also be entered at step S.15, or this data may be automatically
developed or extracted concurrently with the development of the bend model data, as
described below. Other data or information may also be entered at step S.15, or entered after
or during the entry of the bend model data, such as the bend line information which may
comprise, for example, the bend angle, radius and length for each bend line in the part.
After step S.15, logic flow proceeds so that the bend model data may be developed and
entered at server module 32 by an operator, as shown in Fig. 3.
The development and entry of the bend model data may depend upon the original
drawings and information provided from the customer. The customer's order may include,
for example, a 2-D, single view flat drawing of the part to be manufactured and or a 2-D,
three view (e.g., including top, front and side views) drawing ofthe part. Occasionally, the
customer may also provide a 3-D, wire frame drawing of the part, with or without the
thickness of the material ofthe part being indicated in the drawing. In accordance with an
aspect ofthe present invention, the bend model data may include both the unfolded (i.e., the
2-D flat representation) and the folded (i.e., the 3-D representation) information for the part
to be manufactured. Thus, if only a 2-D flat drawing is provided by the customer, it will be
necessary to develop a 3-D drawing ofthe part by applying, for example, a folding algorithm
or process to the 2-D drawing. Alternatively, if only a 3-D drawing ofthe part is provided, then it will be necessary to develop a 2-D flat drawing by applying, for example, an
unfolding algorithm or process to the 3-D drawing. In accordance with another aspect ofthe
present invention, the 2-D and 3-D models that are saved in the bend model may be
developed and represented without the sheet material thickness (i.e., with no thickness).
This is possible due to the unique symmetry of all sheet metal parts. Providing and
representing the 2-D and 3-D drawings with no thickness provides modeling and simulation
views of the part that can be more easily inteφreted and understood by the design
programmer, the bending operator and other users. Removing the thickness information also shortens and improves the processing time required by the server module and station
modules when performing and executing the various features of the invention described
herein. A more detailed description of such features, as well as the folding and unfolding
algorithms that may be utilized in the present invention, is provided below with reference
to the accompanying drawings.
Fig. 3 shows the general processes and operations performed when developing the
bend model data. The various types of drawings that may be received or developed based
on the customer's order and that may be entered to develop the bend model data are
generally shows at steps S.19, S.23, S.27 and S.31. A tool icon bar and menu and/or help
screens may be provided by the server module 32 to assist the operator in selecting and
executing each of these steps. The processing of these drawings to develop the 2-D and 3-D
models of the part for the bend model will depend on what type of drawings are initially
provided. These drawings may be manually entered or developed at server module 32, or
they may be downloaded from a tape or disk. Server module 32 may, for example, interface
with a CAD/CAM system located at, for example, design office 10, or server module 32 may include a stand alone CAD/CAM system. Further, the 2-D and 3-D drawings may be saved as DXF or IGES files and imported to server module 32.
If a 2-D, single view flat drawing is provided, then processing to develop the bend
model may begin at step S.19, as shown in Fig. 3. At step S.19, the 2-D, flat drawing that
was received or developed may be entered at server module 32. Other bend model data,
such the overall dimensions of the part (e.g., width, height, depth), and part material
information may also be enter at step S.19. Thereafter, a folding algorithm or process may be utilized to develop a 3-D model (with no material thickness) based on the original 2-D
single view drawing, as generally shown at step S.21. An example of the processes and
operations that may be performed to develop a 3-D model from a 2-D, flat drawing is
provided below with reference to Figs. 8-1 1.
If a 3-D, wire frame drawing (with no material thickness) of the part is received or
developed, the drawing information may be entered at step S.27. In addition, other bend
model data, such the overall dimensions of the part (e.g., width, height, depth), and part
material information may be entered at step S.27. Thereafter, an unfolding algorithm or
process may be executed at server module 32 in order to develop a 2-D model of the part,
as shown at step S.29. An example ofthe processes and operations that may be performed
to develop a 2-D model from a 3-D drawing (with no thickness) is provided below with
reference to, for example, Fig. 12.
The 2-D and 3-D model representations of the part may be stored as part ofthe bend
model for that part. In addition, as noted above, during the development and entry of the 2-
D and 3-D models, other bend model data may be entered (such as the part material
information and other manufacturing information) so that it may be stored with the bend
model data in database 30. The various features and data structure arrangements that may
be implemented for organizing and storing the bend model data are discussed more fully below (see, for example, Figs. 17 and 18).
As shown in Fig. 3, if a simple 3-D drawing (with no material thickness) of the
component is not originally developed or received, additional processing may be necessary
in order to develop a 3-D model of the part (with no thickness), before executing the
necessary unfolding algorithm or processes to develop the final 2-D model. Steps S.23,
S.25, S.31 and S.33 generally show the additional processing and operations that may be
performed by server module 32 before executing an unfolding algorithm and developing the
2-D model at step S.29.
For example, if a 2-D, three-view drawing of the part is originally provided or
developed, then at step S.23 the drawing may be entered at or imported to server module 32.
Further, other bend model data, such the overall dimensions ofthe part (e.g., width, height,
depth), and part material information may also be enter at step S.23. Thereafter, at step
S.25, a simple 3-D, flat drawing ofthe part may be developed based on the 2-D, three-view
drawing that was entered. The developed 3-D drawing may then be used to develop the 2-D
model at step S.29, as shown in Fig. 3. An example of the processes and operations that
may be performed to develop a 3-D model from a 2-D, three view drawing is provided
below with reference to, for example, Fig. 13.
If, however, a 3-D drawing with material thickness is originally received or
developed, then the drawing information may be entered at step S.31 for further processing
before applying the unfolding algorithm. Other bend model data, such the overall
dimensions ofthe part (e.g., width, height, depth), and part material information may also
be enter at step S.31. Thereafter, at step S.33, an eliminate thickness procedure may be
executed to eliminate the thickness in the 3-D drawing. In accordance with an aspect of the invention, server module 32 may prompt the operator or user to indicate the thickness in the drawing and to indicate which surfaces (e.g., the outside or inside) should be retained when
executing the eliminate thickness procedure. An example of an eliminate thickness
procedure that may be utilized in the present invention is provided below with reference to,
for example, Figs. 15 A and 15B. After the thickness in the 3-D drawing has been eliminated
at step S.33, logic flow will proceed to step S.29, where the revised 3-D model with no
thickness may be utilized and an appropriate unfolding algorithm or process may be applied
to develop the final 2-D model. An example of an unfolding process and the various
processes and operations that may be performed to develop a 2-D model from a 3-D drawing
is provided below with reference to, for example, Fig. 12.
As shown in Fig. 3, after all of the relevant information has been developed and
entered, the part information, bend model information and other data associated with the
customer's order may be transferred from server module 32 and stored in database 30 at step
S.35. The data stored in database 30 may include feature extraction or search data that may
be utilized when performing database searches. As described below, the feature extraction
or search data may include data that is indicative of the basic or key features of the part
associated with each job, so that searches ofthe database may be performed to locate job
information and stored expert knowledge relating to the same or similar parts. The data and
information entered at server module 32 may be sent directly to database 30 or transferred
over communications network 26, as shown, for example, in Fig. 2. As indicated above, a
more detailed description of the various processes and operations that may be performed for
the various drawings when developing the bend model data will be provided below with
reference to the accompanying drawings.
Fig.4 is a flow chart of the basic processes and operations performed by each of the
station modules that may be provided at the locations 10, 12, 14...20 of the sheet metal manufacturing facility 38. For purposes of illustration, Fig. 4 provides an example of basic
logic flow of the processes and operations that may be performed by a station module
located at, for example, bending station 18. As will be appreciated by those skilled in the
art based on the teachings ofthe present invention, the logic flow illustrated in Fig. 4 may
of course be modified for each station module depending upon the nature of the operations
and processes to be performed at each ofthe locations. Further, as with server module 32,
the processes and operations ofthe station module described below may be implemented by
software or programmed logic. In addition, the station module may include a Windows
based application with tool bar icons or help and/or menu screens to facilitate an operator
or user in selecting and executing the various processes and operations ofthe station module.
Such help and/or menu screens may also be provided to facilitate the entry or transfer of data
at the station module.
As shown in Fig.4, after initializing the station module at step S.51 , an operator may input one or more database search criteria or key terms at step S.53. The search criteria may
be entered to locate previous job information or job information relating to a new or current
job that is stored in database 30. The operator may input, for example, a predetermined
reference number or code in order to retrieve particular job information from database 30.
For example, in accordance with an aspect of the present invention, a bar code may be
provided on a routing sheet or may be affixed to the punched stock material and scanned by
a bar code reader at the station module to access the information. Alternatively, the
reference code or number could be entered manually through a keyboard or digital input pad
at the station module. A translation table may be provided so that the file name of the
previousjob information may be determined based on the entry ofthe part reference or job
number by an operator. In addition, it is contemplated that search criteria or keys may be entered to perform a similar part search for previously stored job information. Such a search
may be performed based upon the various design features or feature extraction data ofthe
part. A description of a similar part search that may be implemented, in accordance with an
aspect ofthe present invention, is provided below with reference to Figs. 5-7.
After the search criteria has been entered at step S.53, the station module may
execute a search of the database 30 at step S.55 via communicationsnetwork 26 and network
database module 34. The results ofthe search may then be sent back to the station module
and analyzed at step S.57 in order to determine whether the operator or user has requested
information relating to a new job or a similar previous job, or whether the request relates to
the complete repeat of a previous job.
If an identical match is found (e.g., the same part or reference number is located) and
it is determined that a previous job is to be repeated, then the stored design and
manufacturing information relating to the job may be transferred from database 30 to the
station module, where it may be displayed for viewing by the operator, as generally shown at step S.59. The station module may include one or more menu display screens or
directories to permit the operator to select and display the various information retrieved from
database 30. The operator may review the displayed information and run various
simulations, such as a 3-D bending simulation at step S.61 , to view the various stages in the
bending sequence and to understand the geometry of the part for that j ob . The operator may
also review other information such as the required tooling and any other special instructions
or messages that may have been recorded with the job information. After confirming the job information, the operator can then set-up the bending or other required machinery and
operate the machinery to produce the specified sheet metal components. The job information that is retrieved from database 30 may include the final bending plan data,
including the bending code to control the machinery at, for example, bending station 18.
The set-up and actual operation of the machinery may thus be carried out by the operator,
as generally shown at step S.63 in Fig. 4.
If no identical or similar job information is located and it is determined that the
information relates to a new job (i.e., only preliminary job information has been entered at
the server module 32 and complete job information has not yet been developed), then the
partial part information and bend model data may be downloaded from database 30 and sent to the station module where it may be viewed by the operator at step S.77. Since the
information requested relates to a new job, it will be necessary for the operator to develop
and enter a bending plan, including the required tooling and bending sequence. Thus, at step
S.79, with the information provided at the station module, the bending operator may develop
and define the bending sequence and tooling selection for the new job. As will be discussed
in greater detail below, a graphical user interface (GUI) and other features may be provided
at the station module to facilitate the bending operator in developing the bending plan. The
GUI may be provided to help the operator develop a bending plan by, for example,
displaying tooling options, automatically checking for potential collisions between the part
and tool(s), and simulating each of the intermediate steps in a proposed bend sequence.
After developing and entering the bending plan at the server module, the operator may
program the bending sequence at step S.80 to generate the bending code (i.e., the CNC or
NC code for executing the bend sequence with the bending machinery). The bending code
may be directly entered at the server module or imported to the server module by interfacing
with, for example, a CNC or NC controller of the bending machinery. Thereafter, the operator may set-up and test the bending plan at the bending work station at step S.81.
When all ofthe necessary testing and any necessary modifications to the bending plan have
been completed, the final bending data may be entered and saved to database 30 at step S.83.
The final bending data may include the bend sequence and tool set-up information, as well
as the bending program. This information may be sent from the station module of, for
example, bending station 18 to database 30 so that it may be saved with the other design and
manufacturing information associated with the new job.
If it is determined at step S.57 in Fig. 4 that the information relates to a similar part
of a previous job or the same part of a previous job but having, for example, a different
reference or job number or batch size, etc., then logic flow may proceed to step S.65. At step S.65, the previous job information may be retrieved from database 30 and displayed at
the bending station 18. The bending operator or user may then view the data to determine
which changes to the data will be necessary for the similar part. Once again, the station
module may include a series of menu display screens or directories to enable the operator
to select which information to display and the manner in which the information is to be
displayed or modified. For example, at step S.69, the station module may provide a 3-D
bending simulation based on the retrieved information in order to facilitate the operator's
development of a bending plan for the similar part. After reviewing the previous job
information, the operator may modify the tooling and bending information, as well as the
bending program, at step S.70. Other job information, such as the dimensions of the part,
the reference number or batch size, may also be modified and edited at step S.70.
Thereafter, at step S.71 , actual tooling set-up and testing may be performed by the operator
on the shop floor in order to test the modified bending plan. Upon completion of testing and any further modifications to the bending plan, the operator may enter at step S.73 the final
bending data and store the same in database 30 under a new reference or job number. As
noted above, the previous job information may be maintained in database 30 along with the
other stored job files. Further, various database management functions may be provided for
storing, deleting, renaming, etc. the files stored in the database.
Referring now to Figs. 5-7, a detailed description of an example of a similar part
search function that may be implemented in accordance with the teachings ofthe invention
will be provided. In accordance with an aspect ofthe present invention, a similar part search
procedure may be provided that utilizes a feature based topology similarity search algorithm
to search and retrieve previous job information from database 30. The similar part search
may involve a search for identical and or similar parts based the design features and/or
manufacturing information relating to the part to be produced. Further, the similar part
search may be implemented through use of software or programmed logic residing within,
for example, server module 32 and/or the various station modules throughout the factory 38.
The similar part search may be executed from server module 32 or any of the station
modules of the locations 10, 12, 14...20 within the sheet metal bending factory 38. A high
level programming language, such as C++ or Microsoft's VISUAL C++ programming
language, and object oriented programming techniques may be utilized to implement the
various processes and operations ofthe similar part search.
Figs. 5 A and 5B illustrate the logic flow of a similar part search algorithm or process
that may be utilized. As shown in Fig. 5A, the relevant part model data file may be
accessed at step S.100. The part model may comprise, for example, the bend model data developed at a CAD system located at design office 10 and/or the data developed and
entered at server module 32. The part model data may include, for example, part topology
data representing the orientation, geometric relationships and relative position ofthe various
surfaces or faces and bendlines ofthe part. After the part model data has been retrieved, or
after the bend model data for a part has been manually entered, a feature extraction operation
may be performed at step S.102 to automatically derive feature extraction data for that part
based on the bend model and/or part topology data ofthe part.
According to an aspect of the present invention, feature extraction data may be
derived automatically by analyzing the various features of the sheet metal part. For example, various surface or face features and bend features may be analyzed to determine
the similarities between various parts. For instance, the various faces of a part may be
analyzed to determine whether adjacent faces have open or touching comers. Other features
such as the existence of parallel bends, serial bends, collinear bends or opposite bends may
be analyzed to determine and extract the distinct and unique features of each part.
Table 1 indicates various bend and face features that may be analyzed when
performing a similar part search. The extraction features that should be included in the
feature extraction operation include the positive bend and negative bend features, as well as
the touch comer and open comer features. In addition, the feature extraction operation
should also include at least feature analysis of parallel bends, serial bends, collinear bends,
different phase, collinear bends and thickness offset bends. TABLE 1
Feature Brief Description
PosBend positive bend between two faces
NegBend negative bend between two faces
P90B end 90 degree positive bend angle
N90Beπd 90 degree negative bend angle
MrPosBend multiple positive bendlines between two faces
MrNegBend multiple negative bendlines between two faces
ZBend Z bend heMBend Hemming bend in positive direction hem Bend Hemming bend in negative direction
TouchCnr two faces touched in corners with same bend direction
OpenCnr two faces open in comers with same bend direction
PrllBend two parallel bendlines with same bend angle direction and opposite bendline direction
SerlBend two parallel bendlines with same bend angle direction and same bendline direction cLnrBend collinear bendlines with same bend angle direction on one face
D CInrBend collinear bendlines with same bend angle and on different faces tHkOffBend thickness offset bendlines with same bend angle direction and on two neighboring faces touchCnr two faces touched in corners with opposite bend direction openCnr two faces open in corners with opposite bend direction prllBend two parallel bendlines with opposite bend angle direction and opposite bendline direction serlBend two parallel bendlines with opposite bend angle direction and same bendline direction clnrBend collinear bendlines with opposite bend angle direction on one face thkOfϊBend thickness offset bendlines with opposite bend angle direction on two neighboring faces
NoRelation no relation between two faces
The feature extraction operation performed at step S 102 may include a series of
operations including analyzing the bend model data and topology for each feature,
modifying the topologies, and developing feature based matrices from the topologies for further analysis. For puφoses of illustration, Figs. 6A-6G show an example of a feature
extraction operation for a part consisting of a four bend box with touched comers and a
part consisting of a four bend box with open comers. For puφoses of illustration, Figs.
6A-6G show the feature extraction based on the comer relationshipof adjacent faces. For
a closed, four bend box, with five faces (1-5) such as that shown in Fig. 6A. and for an
open, four bend box, with five faces (1-5) such as that shown in Fig. 6B, the same simple
face topology, such as that shown in Fig. 6C, may be provided to represent either part. This topology may be stored in and provided with the part or bend model data. The
simple face topology of Fig. 6C, however, only provides basic information regarding the
relationshipof the faces (1 -5) of the part and does not provide any information as to the
various features ofthe part, such as the comer relationship between adjacent faces or the
type of bends that are included. Accordingly, during the feature extraction operation, by
analyzing the part or bend model data and the related face topology stored therewith, the
basic face topology may be modified to contain additional information with respect to the
various features of the part.
For instance, by examining the part or bend model data for the closed, four bend
box of Fig. 6 A, the comer relationship of adjacent faces may be analyzed and a modified
face topology, such as that indicated in Fig.6D, may be developed to indicate the touched
co er status ofthe respective faces. Similarly, by examining the part or bend model data
ofthe open, four bend box of Fig. 6D, a modified face topology, such as that shown in
Fig. 6E, may be developed to indicate the open comer relationship between the various
adjacent faces in the part. As shown in Figs. 6D and 6E, special connectors may be added to the face topology to indicate the relationship (e.g., touched or open) between the comers of the faces. Other data may be added to the face topology data structure to
indicate other features (e.g., the type of bends present, etc.) and to developed a featured
based, face topology. After modifying the topology to include the feature based
information, a matrix may be developed so that the extracted information may be more
easily analyzed and compared. For example, based on the feature based face topology
of Fig. 6D, a matrix such as that shown in Fig. 6F may be developed to indicate the
various features of the closed, four bend box of Fig. 6A. Similarly, for the open, four
bend box of Fig. 6B, a matrix such as that shown in Fig. 6G may be developed based on
the feature based face topology shown for example in Fig. 6E. Other feature extraction
data may also be indicated in the matrix, such as the bend features ofthe part (e.g., a 90°
positive bend angle or a 90° negative bend angle, etc.).
As noted above, the features extraction operation of step S.102 may be performed
by analyzing the bend model data and topologies to determine if various features are
present in the part. In accordance with an aspect of the present invention, the feature
extraction operation may be performed on the bend model and topology data provided
for the part. This data includes all ofthe critical geometric and location data (e.g., in 2-D
space (X,Y) and/or 3-D space (X,Y,Z)) relating to the sheet metal part, including face
data, bendline data (e.g., bendline length and location, etc.), face-bendline relationship
data, bend angle data, and special features data (e.g., data relating to special bending such
as Z-bends and Hemming, etc.). The lines, bendlines and other entities may be defined
by endpoints and or vectors. For example, each 2D line may be specified by a set of 2D
endpoints (e.g., XI , Yl and X2,Y2) and each 3D line may be defined by a set of 3D endpoints (e.g., X1,Y1 ,Z1 and X2,Y2,Z2). Bendlines may be represented by vectors, which indicate 2D or 3D space location as well as direction ofthe bendline. Further, 2D
arcs may be specified by 2D space data (e.g., CenterX, CenterY, Radius, Begin Angle,
End Angle) and 3D arcs may be defined by 3D space data (e.g., CenterX, CenterY,
CenterZ, View Matrix, Radius, Begin Angle, End Angle). Part topology data may also
be provided to indicate the location ofthe various faces and bendlines ofthe part, as well
as their geometric relationships to one another. Each face may be defined by a collection
or linked data list of lines and or arcs.
To extract features ofthe part, the feature extraction operation may be performed
on the bend model and topology data to analyze and determine whether certain features are present in the part. This process may include analyzing the bend model and topology
data for the part based on the various characteristics and relationships associated with
each ofthe features to be extracted. By analyzing the bend model and topology data for
the existence of the characteristics and relationships for each feature to be analyzed, the
presence of features (such as a touched co er or open comer feature between faces, or
a parallel or serial bends feature) may be detected. Different processes may be provided
to detect the particular characteristics and relationships of each feature in the feature
extraction operation. Based on the similarity of characteristics and relationships among
the features to be analyzed, processes may be combined or developed to check for the
existence of more than one feature in the part.
By way of a non-limiting example, a process that may be performed during the
feature extraction operation of step S.102 in order to extract and detect comer features,
such as a touch co er feature of two faces having the same bend direction (i.e., a TouchCnr feature in Table 1), will be provided. The process described below may also be applied to detect other features, such as a touch comer feature of two faces having
with opposite bend direction (i.e., a touchCnr feature in Table 1 ) or open comer features
between two faces having the same or opposite bend direction (i.e., a OpenCnr or
openCnr feature in Table 1 ). The process may also be modified to detect other features
(e.g., parallel bends, serial bends, etc.). In addition, the data relating to each possible
combination of faces may be analyzed for the characteristics and relationships of each of
the features to be extracted.
For example, for the touched comer feature TouchCnr, the basic characteristics
or relationship to be detected include: two faces with a common face; the same bendline
directions; non-parallel bendline directions; and bendlines with a common vertex (or
vertices with a distance therebetween that is within a predefined range). For the touched comer feature touchCnr, similar characteristics or relationships should be detected;
however, instead of the faces having bendlines that are in the same direction, the faces
should have bendlines that are in the opposite direction (see. e.g., Table 1 ). The open comer features OpenCnr and openCnr may be similarly detected, however, for each
feature the presence of an open comer between the faces (e.g., the bendlines ofthe faces
are spaced apart by a distance that is greater than a predefined range) instead of a touched
comer relationship, and the detection ofthe bendlines having the same bendline direction
or the opposite direction (see, e.g., Table 1 and the definitions provided therein for
OpenCnr and openCnr) should be analyzed.
To detect the touch comer feature (e.g., the TouchCnr feature in Table 1 ), the
bend model and topology data for any two faces may first be analyzed to determine if the two faces are attached to a common face. This may be detected by looking at the bendline data for each ofthe faces and the bendline-face relationship data for each of the
bendlines to determine if a common face exists. If the two faces are attached to a
common face, then the bendline direction of each of the faces may be analyzed to see if
they have the same bendline direction (or the opposite bendline direction if detecting, for
example, the touchCnr feature). This may be determined by analyzing, for example, the
vector data indicating the bendline direction for each of the faces.
If it is determined that the two faces have a common face and have the same
bendline direction based on the bend model and topology data, then the data may be
checked to detect if the bendlines are parallel. Various methods may be used to detect whether the bendlines are parallel based on the bend model and topology data. For
example, the detection of parallel bendlines may be determined by taking the cross-
product ofthe vectors defining the bendline directions. Ifthe cross-productof the vectors equals zero (or is approximately zero), then it may be determined that the bendlines are
parallel. If the cross-product of the vectors does not equal zero (or is not approximately
zero), then the bendlines of the two faces are not parallel.
After determining that the two faces have a common face, the same bendline
direction and the bendlines are not parallel, then
the bend model data may be analyzed to determine the comer relationship between the
faces (e.g., touched or open). The comer relationship ofthe two faces may be determined
by detecting from the bend model data whether the bendlines ofthe faces have a common
vertex. If the bendlines have a common vertex, then the two faces have a touched comer
relationship with the same bendline direction (e.g., TouchCnr feature in Table 1). If the
bendlines have a common vertex, but it was determined that the bendlines of the two faces do not have the same direction, then it may be determined that the two faces instead
have a touched comer relationship with opposite bendline direction (e.g., touchCnr
feature in Table 1 ).
If the bendlines ofthe two faces do not have a common vertex, then it still may
be determined that the two faces have a touched co er relationship if the distance
between the vertices is within a predefined range. Often, a minimum amount of space
will be provided between adjacent faces ofthe part to provide clearance for passage of,
for example, the punch tool. This spacing is usually defined by the width of the tool at
the height ofthe flange. By way of example, a touched comer feature may be determined
to be present if the spacing between the vertices of the bendlines of the two faces is within 0-5 mm. If the spacing between the comer of the two faces is greater than the
predefined range, then it may determined that a open comer feature is present (e.g., the
OpenCnr or openCnr feature of Table 1).
The above described process may be performed for every possible combination
of faces in the part, to determine the comer feature of each ofthe faces. Other features
relating to the faces and bendlines ofthe part may be conducted in a similar fashion by
analyzing the part geometry and topology data. An exemplary code for performing the
feature extraction operation of step S.102 is provided in Appendix A. The code was
written in C++ programming language and includes the various processes for extracting
and detecting features such as those noted in Table 1. Comments are provided in the
code of Appendix A to facilitate the analysis ofthe logic and algorithms used therein.
In addition, the terminology for the various features in Table 1 is maintained in the sample code to aid understanding ofthe same. After detecting the various features ofthe part, the basic topology ofthe part may
be modified to include the extracted features. While it may be useful to provide feature
based topologies, such topologies can not be easily compared with one another. Instead,
the inventors of the present application have discovered that it is more efficient and easier
to compare feature extraction information when provided in the form of matrices.
Therefore, according to one ofthe features of the present invention, a feature based part
matrix (such as the representative matrix shown in Figs. 6F and 6G) may be created
based on the features detected during the feature extraction operation. The feature based
matrix for the part may then be compared with other predefined and stored matrices to
determine what basic shapes or features are included in the part.
A feature based matrix may be created and stored for each part after detecting and
extracting the various features for the part. As shown in Figs. 6F and 6G, the matrix may
be a two dimensional matrix that is symmetric and that has an order that is equal to the
number of faces in the part. The matrix may contain all of the detected feature
information for the part, with the various features between each of the faces being
provided in each of the locations of the matrix. The feature based part matrix may be
temporari ly stored in the memory of the server or station module and only used and
compared with the predefined matrices during execution of the similar part search.
Alternatively, the feature based part matrix may be permanently stored with the other job
information in database 30 and accessed from any location within the factory.
Referring back to Fig. 5A, after the feature extraction operation has been
performed, the resultant feature extraction data matrix may be compared with predefined feature extraction data matrices provided in a feature topology library. The feature topology library may be stored as a separate datafile in a database, such as database 30,
or the memory of the server module or the station module. The feature library may
consist of predefined matrices with feature extraction data corresponding to or defining
basic or fundamental part shapes (e.g., a four bend box, a bridge, etc.). Each of the
predefined feature based matrices, as well as the feature based part matrix, may be stored
as ASCII or text files. The comparison at step S.104 may be conducted to determine the
basic or fundamental shapes/features that are present in the sheet metal part, as illustrated
at step S.106. A stored lookup table may be provided to indicate which fundamental
shape corresponds to each ofthe predefined feature matrices. When a match is located,
the lookup table may be accessed at step S.106 to determine which fundamental shapes
are present. The matched matrices from the predefined library may be ofthe same order
as the feature based part matrix (in which case the part is determined to exactly
correspond and include only one fundamental shape), or may be sub-matrices of the part
matrix (in which case the part may include more than one fundamental shape).
Recursive programming techniques may be utilized to compare the feature based
part matrix with the matrices in the predefined library. By interchanging the indexes of
the matrices when comparing the information therein, the use of data assignments may
be avoided and the amount of required processing time reduced. The use of recursive
programming techniques and interchanging of indexes also facilitates the comparison of
matrices that have different orders and different base faces.
According to an aspect ofthe present invention, the comparison operation that is
performed at step S.104 may consist of a series of comparisons and may initially begin
based on the comparisons of matrices relating to more complicated shapes (e.g., those - 64 - shapes containing multiple bends or complex forming such as tabs) and then proceed
through less complicated shapes (e.g., those shapes containing fewer bends or less
complex bends or number of faces). This series of comparisons may be performed until
a predetermined number of fundamental shapes are located in the part. For example, the
comparison operation may be performed to extract the three most complicated features
or shapes within any particular part. In addition, this operation may be performed by first
conducting the series of comparisons on groups of matrices that relate to shapes that are
more common or frequently found in sheet metal parts, and then proceeding to less
common shapes. Various methods for comparing the part with the predefined library
may be performed to provide useful results.
For example, the series of comparisons may be first applied to a right angle group
of matrices that include fundamental shapes that include right angle bends, such as
rectangular and square shapes with multiple right angle bends and simple parts with right
angle bends. This group of matrices may be searched based upon a series of comparisons
extending from more complex matrices within the group (e.g., a matrix corresponding
to a four bend box with tabs) to less complex matrices within the group (e.g., a matrix
relating to a simple hat part). The series of the comparisons may then be applied to a
polygonal part group of matrices and then a special features group of matrices. The
polygonal part group may include matrices defining parts having more than five sides and
at least one bend angle that is greater than 90 degrees. The special features group of
matrices may include matrices within the predefined library that relate to parts with
special features or forming, such as Z-bends or Hemming. Once again, the series of
comparisons between the feature based matrix of the part and the predefined matrices within each ofthe groups may be performed based on decreasing levels of complexity.
Thereafter, other groups of predefined matrices may be compared, such as a multiple
features group of matrices that includes parts that have two or more features on a single
face ofthe part.
By comparing the part with the matrices in the predefined library in order of
complexity, and by applying the series of comparisons to groups of matrices based on
frequency of appearance and use, a more effective and efficient comparison ofthe library
may be conducted to determine the fundamental shapes in the part. In addition, an
overlap of detected features is prevented and only the more complex shapes are identified.
At step S.108, a feature relation operation may be performed to determine the
relationship between the fundamental features or shapes located in the part. The relation
between the features or shapes may be defined in terms of distance. The distance
between any two shapes may be determined based on the number of bendlines or faces
between the base face of each of the shapes. Altematively, the relationship between
features may be defined in terms ofthe physical distance or real dimension between the
features, by geometrically analyzing the part and the relative position and distance
between the base face of each ofthe features.
Assume, for purposes of illustration, that the three most complicated features or
shapes determined at step S.106 for the part consist of a four bend box, a bridge, and
another four bend box, as shown in Fig. 7A. A feature relation operation performed on
such a part may be conducted to determine, for example, the number of bendlines
between the base surface or face of each fundamental feature. As shown in Fig. 7B, the feature relation between the base (1) of the first four bend box and the base (2) of the
bridge is a spacing of two bendlines. Further, the relation between the base (1) of first
four bend box and the base (3) ofthe second four bend box is a spacing of four bendlines,
and the relation between the base (2) of the bridge and the base (3) of the second four
bend box is a spacing of two bendlines.
Various processes may be provided for determining the number of bendlines
between the base faces of the fundamental shapes of the part. For example, a matrix
analysis of the feature based part matrix and the predefined shape matrices may be
utilized to determine the feature relation in step S.108. First, the corresponding base
faces of each ofthe fundamental shapes may be located in the part matrix. This may be performed by correlating the base face ofthe predefined shape matrix with the face index
in the part matrix. As discussed above, the predefined shape matrices isolated during the
comparison operation may be sub-matrices of the part matrix. In order to locate the
corresponding base face for each fundamental shape in the part matrix, the location ofthe
shape matrix within the part matrix and the correlation between the indices of the
matrices may be analyzed. With the base face of each of the fundamental shapes being
predefined and located within the first column of the shape matrix, the corresponding
location and base face within the part matrix may be located.
After determining the base faces of each of the fundamental shapes in the feature
based part matrix, the distance between the base faces of each shape may be analyzed to
determine the feature relationships. This analysis may include a search process to identify the distance between any two base faces. By looking at the feature and bendline
information in the part matrix, the number of bendlines between any two base faces may be determined. If more than one path is possible between two faces, the minimum
distance may be used to define the feature relation at step S.108.
After performing the feature relation operation, logic flow continues to step
S.110. As shown in Fig. 5B, an identification of database search keys may be performed
at step S.110 in order to determine the search keys to be utilized in the similar part search
ofthe database. The search keys may consist of any number of combination of features
and feature relations identified for the part. In addition, any hierarchy of criteria may be
used for assembling the search keys. By way of a non-limiting example, the search keys
may be developed by the following criteria: (i) the first and second most complicated
features or shapes identified in the part; (ii) the distance or feature relation between the
two most complicated features; (iii) the third most complicated feature or shape identified
in the part; and (iv) the feature relation or distance between the first most complicated
feature and the third most complicated feature, and the distance or feature relation
between the second most complicated feature and the third most complicated feature
identified in the part. Fig. 7C illustrates the search keys that may be developed based on
the example of Fig. 7A.
In order to simplify the search ofthe database, the search keys may be represented
by a string of integers, with predetermined codes being assigned to the various
fundamental shapes defined in the topology library. For example, assume that the integer
code " 16" was assigned to a four bend box, and that the integer code "32" was assigned
to a bridge. In such a case, the search keys of the example in Fig. 7C would be
represented by a string of integers comprising "16, 16, 4, 32, 2, 2", wherein "4" and "2"
represent the various distances between the fundamental shapes or features. The representation of the search keys, however, is not limited to integer strings and any
combination of integers and/or character strings may be used to represent the search keys.
The search keys for each part may be stored with the job information (as a
separate file or in the same file) in a database, e.g., database 30. The search keys, which
are representative of the feature extraction data, may be manually entered or
automatically developed, as described above. Additional feature extraction data, such as
the feature based part matrix, may also be stored with the search keys. If the search keys
are stored in a separate data file, a lookup table may be provided for locating the part
information associated with each set of search keys. Altematively, the search keys may
be saved with a data field identifying the part information (e.g., by part or reference
number).
At step S.l 12, a cooperative search of the database is performed based on the
identified search keys. The cooperative search is a search using a cooperative database
search technique. The cooperative search technique not only locates parts with identical
search keys, but also parts having similar search keys. This enables the identification of
similar and identical parts in the database. When a search is performed based on a
particular part, the identified search keys for that part may be compared with the other
search key data in the database. The cooperative search performed at step S.112 may be
adapted to identify those items in the database which exactly match or are most similar
to a particular part defined by the search keys, by relaxing or modifying the sequence of
search keys. Various processes and methods may be employed for adapting the search
keys during the cooperative search.
For example, an initial search ofthe database is performed to identify parts having the exact sequence of search keys as that identified for the part to be searched. This is
performed by comparing the identified search keys with the search keys stored in the
database. After identifying the parts (if any) with the same search keys, subsequent
searches of the database may be performed based on different modified search key
sequences to locate other similar parts. Initially, the items or criteria within the search keys that are less critical or sensitive (such as the feature relation or distances) may be
modified and searched before modifying the more critical or sensitive search items (such
as the fundamental features or shapes located within the part). In addition, each of these
items may be modified in terms of their importance, with more weight or importance
given to those items relating to the first and second most complicated features or shapes
located in the part. For instance, a first subsequent search may be performed after
modifying the defined distances between the third most complicated feature and the first
and second most complicated features. The distance may be modified by increasing the
distance by a predetermined number of bendlines (e.g., 1 -3) or defining a predetermined
range for the distance based on the current value for the distance. Thereafter, the distance
between the first and second most complicated features or shapes may be altered to
provide another set of modify search keys for searching the database. After modifying
the feature relation or distance search keys for the part, the identified shapes may be
altered to derive additional modified search keys in the cooperative search. For example,
the search key item relating to the third most complicated feature or shape may be
changed to a related but less complex shape depending on the current feature or shape
(e.g., from a four bend box with tabs to a simple four bend box). In addition, the search
keys for the first and second most complicated features may be similarly altered to provided further modified search keys for the cooperative search.
The manner in which the distance and feature/shape related to the search keys are
modified during the cooperative search may be executed according to various methods
and techniques. As described above, the amount by which to vary the distance may
depend on the current value ofthe distance. The distance amount (e.g., 4 bendlines) may
be modified to a distance range (e.g., 3-5 bendlines) to expand and make the search more
cooperative. For the features or shapes, modification of the search keys may also be
performed to identify similar parts. The features or shapes may be modified through a
hierarchical structure of feature types. For example, the current feature type (e.g., a four
bend box) may be modified to a less complex feature type (e.g., a three bend box) that
is related and within the same feature type. The hierarchical structure by which the
features/shapes are modified may be predetermined and developed based on different
methodologies, such as type abstraction hierarchy (TAH). More information on TAH
and TAH generation are provided, for example, in CHU et al.. Wesley W., Cooperative
Ouerv Answering via Type Abstraction Hierarchy. CSD-900032, Department of
Computer Science, University of California, Los Angeles, (October 1990) and CHIANG,
Kuorong, Automatic Generation of Type Abstraction Hierarchies for Cooperative Ouerv
Answering, a dissertation submitted as part of the requirements for a Degree of
Philosophy in Computer Science, University of California, Los Angeles, (1995), the
disclosures of which are expressly incoφorated herein by reference in their entireties.
Other processes and steps may be performed during the cooperative search. For example, in addition to searching the database based on the identified search keys relating
to the features of the part, searching may also be performed based on search criteria relating to the manufacturing information for the part. For instance, additional search
keys may be utilized to compare, for example, the machine set-up required for each part.
The machine set-up information may include the type of machine or machinery required
to produced the part, the tool(s) and tool set-up used to produce the part, and/or the
backgaging setting(s) ofthe machinery. The additional search keys may be developed
based on the machine set-up information and/or other manufacturing information and be
used along with the identified search keys when performing the cooperative search ofthe
present invention. As a result, the parts that are identical or similar to the part to be
produced may be identified based on both the design and manufacturing features ofthe part.
In order to select the most similar parts, a selected parts search may be executed
at step S.l 14 to perform a more detailed comparison ofthe results from the cooperative
search and to select a predetermined number of parts that are the same or most similar to
the part searched. The selected parts search may involve the analysis of additional
information or characteristicsof each ofthe parts identified from the cooperative search.
This may involve analyzing various features ofthe located parts, such as the dimensions
ofthe part or the types of holes or openings in the part, which are not provided from the
search key data. This may also involve comparing the manufacturing information
relating to each of the located parts, such as the machine set-up required for each part.
As noted above, the machine set-up information may include the type of machine or
machinery required to produced the part, the tool(s) and tool set-up used to produce the
part, and or the backgaging setting(s) ofthe machinery. In order to perform the selected
parts search, the bend model and other job information for each part may be accessed from the database based on the search keys identified during the cooperative search. As
noted above, a lookup table or additional data field may be provided to provide the job
reference number or code associated with each set of search keys. After retrieving the
part information from the database, the additional information concerning each part (e.g.,
part dimension, material type, special forming, part holes or openings, etc.) may be
analyzed to determine which parts are most similar to the part searched. This process is
optional and may act as an additional
screening process for selecting and grouping those parts from the database that are most
similar to the part. By analyzing and matching this additional information or
characteristics of the part, the selected parts search may be performed to identify or select a predetermined number or set of most similar parts. For example, the selected
parts search may identify the five most similar parts based on the number of matching
search keys and matching additional part characteristics. The number of parts to be
selected from the selected parts search is not limited to five, and may be selected based
on the needs of the factory and the number of the parts actually stored in the database.
This number may also be selectively modified to provide more effective and useful
search results, and the user may be given the opportunity to modify this number to vary
the search set.
After performing the selected parts search, a similarity index may be calculated
at step S.1 16 to rank the parts (in terms of similarity of features and number of matching
search keys) identified in the selected parts search. The similarity index may be
calculated and provided as output at the server or station module at step S.1 18, so that the
user may select which job files are to be retrieved from the database and provided for viewing. The similarity index may provide a ranking ofthe selected parts (e.g., a ranking
of 1 through 5 with the job or reference number for each part) based on the level of
similarity of features between the selected parts and that ofthe searched part. For this
puφose, the feature based matrix for each ofthe parts may be compared to that ofthe
searched part. Comparing the feature based matrices may provide a better indication of
the similarity between the selected parts and the searched part. As noted above, a feature
based part matrix may be stored along with search keys for each part. However,
permanently storing the feature based part matrix for each previous job along with the
search keys may unnecessarily take up a large amount of memory space (particularly
when a large number of parts are stored on the database). As such, it is possible to only
store the search key data for each of the parts and to automatically generate the feature
based matrix for each ofthe selected parts when a similar part search is performed.
Accordingly, after the bend model and other job information has been retrieved
for each of the selected parts, a feature based matrix may be developed through the
feature extraction operation of the invention, as described above with respect to step
S.102. The feature based matrix for the searched part, which may be temporarily stored
during a similar part search, may then be compared with each of the developed feature
based matrices of the selected parts. Various methods and processes may be utilized to
compare the feature based matrices ofthe parts and to determine the similarity between
the parts. For example, for each feature based matrix of the selected parts, the locations
within the matrix may be compared with those ofthe searched part. Each location within
the matrices may be compared based on recursive programming techniques. The information in the matrices may be compared by determining the location of corresponding base faces in each matrix and interchanging the indexes of the matrices.
Since the selected parts may correspond to or have shapes that are sub-features of the
searched part, and since the indexes ofthe matrices may not be identical or numbered in
the same way, it will be necessary to locate comparable faces in the part matrices and to
switch the indices when comparing the information therein. In addition, where more than
one sub-feature is located in a searched part, it may also be necessary to introduce one
or more pseudo faces (i.e., face columns and rows in the matrix with no or blank
information) in order to provide matrices of the same order when comparing the
information in the matrices. When comparing the information in the matrices, different ranking schemes may
be used in order to determine the level of similarity between each of the selected parts
and the searched part. For example, a penalty based ranking scheme may be used
wherein a predetermined penalty level or amount is assigned for each non-matching
location within the matrix. After comparing all of the information in the matrices, the
total penalty level for each selected part may then be used to determine the similarity
index. The selected part with the lowest penalty level may be determined to be the most
similar part to the searched part. The other selected parts may also be ranked based on
the total penalty level associated with each part (e.g., the lower the penalty level the
higher the similarity index). In accordance with another aspect of the present invention, the penalty levels for
each non-matching location may be assigned based on the type of information located
therein. The penalty level may be an integer amount and may be varied based on the
criticality or importance ofthe non-matching information. For example, a higher penalty level or amount may be assigned for non-matching locations relating to different and
unrelated feature groups (e.g., a parallel bend feature versus a serial bend feature). In
contrast, for non-matching locations relating to different but similar feature groups (e.g.,
a touch comer feature with same bendline direction versus a touch comer feature with
opposite bendline direction). The penalty levels or amounts may be predetermined and
categorized based on the type of information and the type of difference present for non-
matching locations.
An exemplary code for performing the similarity index operation of step S.l 16
is provided in Appendix B. The code was written in C++ programming language and
includes the various processes and operations described above with respect to comparing the matrices and assigning penalty levels for non-matching location. As noted above, the
resultant total penalty levels for each selected part that was compared may be used to
derive and display the similarity index. The code listing in Appendix B includes
comments to facilitate understanding ofthe logic and structure ofthe exemplary program
code therein.
Referring now to Figs. 8- 16, a more detailed description ofthe various processes
and operations that may be performed for developing the bend model data and developing
the 2-D and 3-D models of the part based on various 2-D and 3-D drawings will be
provided in accordance with an aspect ofthe present invention. As discussed above, the
bend model data associated with each sheet metal component includes data relating to
both the 2-D and 3-D representations of the part. Based on the type of original drawings
provided or developed based on the customer's order, various folding and unfolding algorithms and other processes may be utilized to develop the 2-D and 3-D models. In particular, Figs. 8-1 1 show an example of the logic flow of the folding algorithm and
other processes that may be utilized for developing a 3-D model based on an original 2-
D, single view drawing ofthe part. Further, Fig. 12 shows an example ofthe basic logic
flow of the unfolding algorithm and other processes that may be used for developing a
2-D model based on an original 3-D drawing (with no thickness). Lastly, Figs. 13-15 and
Fig. 16 show examples ofthe logic flow ofthe various processes and operations that may
be implemented to develop a 3-D model with no thickness from, respectively, a 2-D,
three view drawing and a 3-D drawing with thickness. The resultant 3-D model (with no
thickness) that is developed from these processes and operations may then be utilized to
develop a 2-D model based on an unfolding algorithm or process, such as that disclosed
herein.
Fig. 8 illustrates the logic flow ofthe processes and operations for developing a
3-D model from a 2-D, single view drawing using a folding algorithm. The functions and
operations performed in the flow chart of Fig. 8 may be implemented with software or
programmed logic residing in, for example, server module 32. At step S.120, the 2-D,
single view flat drawing that was provided or originally developed based on the
customer's specifications is entered or imported to the server module 32. The 2-D flat
drawing may be developed and entered into the server module 32 through the use of CAD
software, or may be imported to the server module by interfacing with an appropriate
CAD or CAD/CAM system, such as VELLUM or CADKEY. The 2-D drawing may be
stored, for example, as a DXF or IGES file and may illustrate the punched and/or cut
stock material that is to be bent. The 2-D flat drawing may also indicate the location of the bending lines and the location of holes or other openings in the surfaces or faces of the sheet metal part. In order to prepare the 2-D drawing for later processing, an auto-
trimming and cleanup function may be performed by server module 32 at step S.122,
before a succeeding face detection process is performed at step S.124 and a bendline
detection operation is executed at step S.I 26.
The auto-trimming and cleanup function ofthe present invention is provided in
order to prepare the 2-D flat drawing for processing. The 2-D flat drawing is a 2-D
representation of the sheet metal part in its unfolded state and includes part entities, such
as lines and arcs, that make up and represent the geometry ofthe part, as well as indicate
the location of any openings or holes in the part. Normally, the entities of such 2-D flat
drawings are entered and developed using a CAD or CAD/CAM system. However, when
constructing the 2-D flat drawing, such entities are often improperly connected or
overlapped, and a single entity may be used to indicate the boundaries of more than one
face. Further, outside lines defining the boundary ofthe part may be disconnected at their
adjacent comers, making it difficult to detect the out dimensions of the part and each
face. Further, the 2-D flat drawing may include extraneous information, such as
dimensional information and text. Such irregularities make it difficult to properly
analyze the original 2-D drawing and to uniformly detect the faces and bendlines ofthe
part. By providing the auto-trimming and cleanup operation of the present invention,
each ofthe faces may be represented by a unique set of connected entities. As a result,
the 2-D flat drawing may be more easily and efficiently analyzed for subsequent
processing and eventual folding in order to develop the 3-D model representation.
As shown in Fig. 9A, an original 2-D drawing may not provide trimming between faces and a single line entity in the drawing may define the outer boundary or boundaries of more than one face. As discussed above, such an arrangement makes it difficult to
detect each of the faces. The auto-trimming function of the present invention may be
provided to analyze the end points and intersection points of each of the part entities
(such as lines, arcs and bendlines), in order to determine connectivity information and to
break such entities at their intersection points. Such a trimming function may include
setting the endpoints for each ofthe broken entities to the determined intersection point.
For example, trimming of the intersection point illustrated in Fig. 9A would result in
three meeting entities (two lines and one bendline), each having a common endpoint at
the intersection point. By providing such a trimming function, the faces of the part may
be more easily detected based on entity analysis and connectivity. A more detailed
description of a face detection operation that may be implemented is provided below with
reference to Figs. 10A-10G.
Various processes and operations may be utilized to detect the intersection points
of the entities of the 2-D drawing. Such processes and operations may be developed
based on the format and arrangement of the data in the 2-D drawing file. Typically, a 2-
D flat drawing will include geometrical data (defining the various part entities, etc.) and
non-geometrical (e.g., text, etc.) data. It is possible to distinguish between the
geometrical data from the non-geometrical data based on the keywords provided for each
line or sequence of data. Such keywords are set in accordance with the data format ofthe
2-D drawing. Common formats for 2-D and 3-D drawings include DXF and IGES
formats. By analyzing the geometrical data for each of the entities, the end points and
intersection points for such entities may be detected and, where appropriate, trimming
may be performed. As discussed above, the lines, bendlines and other entities may be defined by
endpoints and/or vectors. For example, for a 2-D flat drawing, each 2-D line may be
specified by a set of 2-D endpoints (e.g., XI, Yl and X2,Y2) and bendlines may be
represented by vectors, which indicate 2-D space location as well as direction of the
bendline. Further.2-D arcs may be specified by 2-D space data (e.g., CenterX, CenterY,
Radius, Begin Angle, End Angle). The geometrical data may also include attributes to
distinguish between the various types of line entities (e.g., arc, solid line, dashed line,
dot-dashed line. etc.). Typically, arc entities are used to indicate holes and openings in
a sheet metal part, and solid lines are used to indicate the boundaries and shape of the
part. Bendlines are usually represented by dashed lines, and the centerline ofthe part is
represented by a dot-dashed line.
The geometrical data from the original 2-D flat drawing may be analyzed to
determine the intersection points between each entity. Various data analysis techniques,
such as data assignment or recursion, may be used to analyze the geometrical data for
each entity ofthe 2-D drawing. Based on the endpoints and/or other 2-D space data for
each entity, simple geometrical analysis may be applied to determine whether lines and
other entities intersect. If two entities are determined to intersect, then each entity may
be broken at the determined intersection point and the resultant entities may have their
endpoints assigned to a common point defined by the intersection point.
The manner in which trimming is performed may be based on the type of entities
that are detected to intersect. For example, if two solid line entities are detected to intersect, then each line entity may be broken to provide four line entities that meet at the determined intersection point, as shown in Fig. 9B. Further, if a line entity and arc entity are determined to intersect, such as that shown in Fig. 9C, then each entity may be broken
to provide two line entities and arc entities that have common endpoints. Detection ofthe
intersection of other entities, however, may not result in trimming. For example, if any
entity is determined to intersect with a centerline (e.g., a dot-dashed entity), then no
breaking of the entities is required, since the centerline of any part does not define or
distinguish the faces or bendlines of the part and trimming is not required. In addition,
unconnected entities may be broken if the open intersection or area is within a
predetermined tolerance. For instance, if the endpoint of a potentially intersecting line
is within a predetermined tolerance or distance e (e.g., 0.0 - 0.01 mm, or 0.0 - 0.001
inches) of actually intersecting another entity, then the entities may be treated as
connecting and intersecting at that projected point; and the entities may be broken, as
shown, for example, in Fig. 9D.
After auto-trimming has been performed, the resultant data may then be processed
by a cleanup function to detect and correct non-connected entities; however, the present
invention is not limited to such processing; and, in order to reduce processing time, the
cleanup function may performed simultaneously with the auto-trimming function while
each ofthe entities are being analyzed. During cleanup, the geometrical data ofthe 2-D
drawing is analyzed to detect open intersections or areas between adjacent entities. As
with the auto-trimming function, the endpoints and other 2-D space data of each entity
may be analyzed to detect an open intersection areas between the entities. Simple
geometrical analysis may be applied to such data to determine whether the endpoints of
the entities are within a predetermined tolerance or distance ε (e.g., 0.0 - 0.01 mm, or 0.0 - 0.001 inches) of one another. If the endpoints of the entities are determined to have such an open intersection, then the entities may be connected and assigned a common
endpoint, such as that shown in Fig. 9E.
Once again, the manner in which the cleanup function is performed may be
controlled based on the type of entities that are detected to have an open intersection. If
two solid lines are detected to have an open intersection, then the endpoints ofthe lines
may be assigned a common endpoint (see, for example, Fig. 9E). However, if any entity
is determined to have an open intersection with a centerline of the part (e.g., a dot-dashed
entity), then the entities should not be connected nor assigned a common endpoint and
the centerline entity should be ignored. In addition, the cleanup function may include
additional processes or operations for deleting the non-geometrical data (text, etc.) from
the 2-D drawing. As noted above, the non-geometrical data may be distinguished from
the geometrical data based on the keywords provided with the 2-D drawing data. The
cleanup function may also incoφorate other cleanup functions, such as those described
in greater detail below with reference to the 2-D cleanup function ofthe invention (see,
for example, Figs. 14A- 14E).
After the auto-trimming and cleanup functions are performed at step S.122, a face
detection procedure may be performed on the processed 2-D drawing, at step S.124. In
accordance with an aspect of the present invention, the face detection procedure may
include face detection logic for detecting and defining the faces of the part based on
entity (line and arc) and loop analysis. Figs. 10A-10H illustrate an example of the
various processes and operations that may be performed in the face detection procedure.
Loop detection techniques may be used in the present invention to determine and detect the faces ofthe part. The face detection procedure may be implemented through software or programmed logic residing at, for example, server module 32.
According to an aspect ofthe present invention, a loop detection analysis of the
outside boundary ofthe part followed by analysisof the minimum or inside loops ofthe
part may be utilized to detect each of the faces. Due to the unique geometry of sheet
metal parts, the faces and openings ofthe part may be detected based on the analysis of
the sequence ofthe relative maximal (e.g., outside) and minimal (e.g., inside) loops. As
discussed below, loop analysis may be performed based on the connectivity ofthe line
and arc entities ofthe part. By performing loop analysis from the outside ofthe part and
proceeding towards the center of the part, the openings and faces of the part may be detected based on the boundaries defined between the loops in accordance with a cyclic
sequence (e.g., face material, opening, face material, opening, etc.).
Assume that a 2-D flat drawing, such as that shown in Fig. 1 OA, is provided with various line entities for each face as shown in the drawing. As noted above, loop and
entity analysis may be performed by starting from the outside boundary ofthe part. Any
entity on the outside boundary of the part may be used as an initial reference point. By
way of non-limiting example, the left most side line entity may be detected and used as
an initial reference point, as shown in Fig. 10B. The left most side line entity may be
detected by comparing the geometrical data of each ofthe entities in the 2-D drawing and
determining which entity has the lowest X-coordinate value. After the left most line
entity has been detected, an outward appearance ofthe part may be derived from a point
PI to detect the outside boundary of the part, as shown in Fig. IOC. Either endpoint of
the left most line entity may be used to define point PI . In the illustrated embodiment
of Fig. IOC, the upper endpoint (i.e., the endpoint with the greatest Y-coordinate value) has been used as point PI .
Conventional loop analysis techniques may be used to derive the outward
appearance or loop about the part. For example, lead line vectors may be projected from
the initial point P 1 and the endpoints ofthe connecting entities as the outward appearance
ofthe part is followed. As each entity is detected and traversed, a flag may be provided
to indicate that the entity has been picked (e.g., a flag in memory may be set to 1 to
indicate that it has been selected once). The loop path may be initiated in either direction
from the initial point P 1. For example, the lead line vector may be projected in the
counterclockwise direction (e.g., by projecting the lead line vector in the Y-coordinate
direction) from the point PI . The loop is completed when the loop path returns to the
initiating point (i.e., point PI).
As noted above, from the initial point PI a lead line vector may be projected in
the counterclockwise direction (e.g., by initiating the first lead line vector in the Y-
coordinate direction). Thereafter, in order to detect the first entity in the path ofthe loop,
the angle that each unselected entity about point PI forms with the lead line vector is
measured and analyzed based on a coordinate frame, with the entity that forms the
smallest angle with the lead line vector being selected. For the outside loop, each angle
may be measured based on the outside angle that the entity line forms with the lead line
vector. The entities about point PI may be determined based on which entities have an
endpoint that is common to point PI. The unselected status of each entity may be
determined by analyzing the flag associated with each entity. As shown in Fig. 1 OC, two
entity lines (one extending in the X-coordinate and one extending in the Y-coordinate) are provided about P 1 in the exemplary 2-D drawing illustrated therein. When analyzing these entities, the line entity that extends in the Y-coordinate would be selected since it
forms a smaller angle (i.e., 0 degrees) with the lead line vector than the angle (i.e., 270
degrees) ofthe other line entity.
The loop analysis would then continue to the other endpoint ofthe selected line
entity, which would have a flag set to indicate that it has been selected. At that endpoint,
another lead line vector would be projected and the unselected entities about that point
would be compared to determine which forms the smaller angle with the lead line vector.
Once again, the angle should be measured from the outside of the lead line vector and a
coordinate frame may be used to determine the angle amount. If an arc entity is
encountered, then the angle should be measured from the outside of the lead line vector
to a line that is tangent to the arc. Further, if only one entity is about the next endpoint
(such as at the comer positions of the part), then no comparison is necessary and that
entity is simply selected and included in the loop.
As the loop path proceeds about the outward appearance ofthe part, each selected
entity may be included in a linked list to indicate the connectivity of the entities within
the loop. When the path returns to the initial point P 1 , the cycle is complete and the loop
may be defined (L4) based on the outward appearance and the linked list of entities or
lines that indicate the outside boundary of the part. Each of the lines or entities within
the loop L4 may be connected at their end points. The direction ofthe loop L4 may be
tumed in the opposite direction (i.e., clockwise), as shown in Fig. 10D. in order to
indicate that it is an outside loop. The direction ofthe loop may be defined based on the
order in which the lines are linked in the loop L4; and, thus, the direction may be changed
by reversing the order of the link list. After the outward loop has been completed, inside loop analysis ofthe part may
be performed based on a similar process to that used for the outside loop analysis. In the
inside loop analysis, however, each ofthe unselected entities are compared based on the
inside angle that each entity forms with the lead line vector. Further, during the inside
loop analysis, where both entities about a point are indicated as being selected (e.g., when
comparing two outside line entities which border a face), the two entities may still be compared unless they have been selected twice (i.e., a flag setting of 2). When there is
an entity that has been selected at least once (e.g., an outside entity) and an unselected
entity (e.g., an inside entity), no comparison may be performed and the unselected entity
may be selected as part of the loop. Figs. 10E-10G illustrated exemplary inside loops
that may be performed to detect and define the faces ofthe part shown in Fig. 10A.
The inside loop analysis may begin at any ofthe outside entity endpoints or by
detecting an entity that has not been selected. For example, point P 1 may be selected to
initiate the inside loop analysis and may be used to project the lead line vector;
altematively, one ofthe inside line entities that was not selected during the outside loop
analysis may also be used as an initial point for analysis. As with the outside loop
analysis, the lead line vector may be extended in the counterclockwise direction (e.g., by
initiating the first lead line vector in the Y-coordinate direction). Each entity about point
P 1 is then compared to determine which entity forms the smallest angle with the lead line
vector. A coordinate frame may be used to determine the angle formed with the lead line
vector. As noted above, during inside loop analysis the entities are compared based on
the inside angle that each entity forms with the lead line vector instead of with the outside
angle. After the initial entity has been selected and included in the linked list for the loop, its flag may be increment by one and further analysis may be performed by
projecting the next lead line vector. The process continues until the loop returns to the
initial starting point, at which point the first inside loop is defined (e.g., Ll) by its
associated linked list of entities.
Further inside loop analysis may performed in a similar fashion by proceeding
inwardly of the part. Subsequent starting points may selected by determining which
entities have been only selected once. Entities with flags that have been selected twice
will indicate that it is an outside entity that has already been selected for the outside loop
(e.g., L4) and for at least one of the inner loops (e.g., L 1 ). Once again, as each entity is
selected, its associated flag may be incremented by one to indicate that it has been
included in the inside loop link list.
After all ofthe inside loops have been defined (e.g., after all of the entities have
been selected twice in the example of Fig. 10G), the resultant loops may be used to
construct a loop tree. Fig. 10H illustrates an exemplary loop tree that may be defined
based the detected loops L1-L4. The outside loop (L4) ofthe part may be defined as the
root ofthe tree, with each inside loop (L1-L3) that has a common entity with the outside
loop being defined as children of the root. The presence of common entities may be
detected based on analyzing and comparing the linked list of entities that define each
loop. If additional entities (e.g., holes or openings) are detected within the inside loops,
then these loops may be defined as children ofthe inside loops (i.e., grandchildren ofthe
root of the loop tree) within which they are located.
After the face detection procedure has been performed at step S.124, a bendline detection operation may be performed at step S.126. As shown for example in Fig. 11 A, when detecting and analyzing the loops of a part at step S. I 24. the face detection logic
of the invention may utilize the loop tree to define the face information and store the
detected faces as nodes in a bend graph data stmcture. The faces of the part may be
detected from the sequence ofthe outside and inside loops in the loop tree. As indicated
above, each ofthe loops may include a link list of entities or lines. These entities may
be used to define the boundaries of each face of the part. The bendline detection
operation of step S.126 may then be performed to determine the relationship between the
faces and bendlines of the part. The bendline detection operation of step S.126 may
include bendline detection logic for detecting all of the bendlines between the various faces ofthe part by searching for common edges or line entities between any two adjacent
faces. Further, for faces that connect at more than one area (e.g., when applying the
bendline detection algorithm to a 3-D model - see, e.g., Fig. 12 discussed below) a
number of heuristics may also be applied to detect and select the minimum number of
bendlines for the part. The detected bendlines then may be stored as connecting agents
between the face nodes to produce the final bend graph data stmcture, as shown for
example in Fig. 1 IB.
The bendline detection operation ofthe present invention may be implemented
through software or programmed logic residing at, for example, server module 32. The
purpose of the bendline detection operation is to detect and select the bendlines for the
part so that the part becomes connected with the minimum number of bendlines. The
bendline detection operation may be provided for both 2-D and 3-D versions of the part.
A discussion of an application of the bendline detection operation in connection with an
original 3-D model is provided below with reference to Fig. 12. As noted above, the detected bendlines may be stored as connecting agents between the
face nodes to produce the final bend graph data stmcture. This final bend graph data
stmcture may then be utilized to fold and construct the 3-D version ofthe part from the
2-D data model.
The original 2-D drawing that is provided as input at step S.120 in Fig. 8 may not
include bendline information or such bendline information may be ambiguous and not
uniquely or consistently defined. Thus, the bendline detection operation may be performed to detect the bendlines and their relation to the detected faces of the part.
During this process, the linked list of entities defining each ofthe faces may be analyzed
to determine adjacent edges or line entities that each face has with other faces ofthe part.
This may performed by analyzing all possible contacts between any given two faces. A
contact may be determined based on the presence of a common line entity (or entities that
are within a predetermined distance tolerance of one another) that has a length that is
greater than 0 (i.e., the line entity is not a point but a real line). The geometrical data in
the linked lists may be analyzed to determine the presence of such contact between any
two faces in the part.
If a particular face only has one common edge or area of contact with another
face, then the entity that is common to both faces may be defined as a bendline. For faces
that have common contact at more than one area (e.g., a 3-D model; however, this may
occur with 2-D models as well), a number of heuristics may be applied to detect and
select the minimum number of bendlines for the part. The heuristics that are applied
should be adapted so that the faces ofthe part become connected at the bendlines and so that no continuous loop of faces is formed (since such a bend sheet metal part is impossible to manufacture).
For example, one such heuristic that may be applied is to select the common area
that has the longest contact area as the bendline. Thus, where a face has more than one
common edge with other faces, this heuristic may be applied so that the common entity
having the longest length is selected as the bendline for the face. This heuristic is based
on the principal that is usually better to have a longer contact area when manufacturing
bent sheet metal parts. Another heuristic that may be applied relates to selecting among
different possible combinationsof bendlines (such as when determining the bendlinesfor
a 3-D model). According to this heuristic, when all possible common areas are detected
and various combinations of bendlinesmay be selected, the combination of bendlines that
produces the minimum number of bendlines is selected.
After the bendlines have been detected, the faces ofthe part and the determined
bendlinesmay be displayed to the operator for verification. If the operator is not satisfied
with the selection of bendlines for the part, the bendline detection operation may provide
a manual selection feature to permit the operator at the server module 32 to selectively
indicate the preferred bendlines for the sheet metal part. The operator may indicate to
keep or change a bendline by any suitable input means, such as a mouse or keyboard, etc.
The revised bendlines selected by the operator may then be used for developing the final
3-D (or 2-D) part.
Various processes and operations may be provided to implement the bendline detection operation ofthe present invention. An exemplary code for implementing the
bendline detection operation is provided in Appendix C attached hereto. The sample
code was written in C++ programming language and includes comments to facilitate the understanding of the logic flow therein. The sample code is an exemplary
implementation for the bendline detection operation that may be performed on a 2-D or
3-D model, and includes heuristics (such as those described above) for determining the
optimum selection of bendlines.
The detected face and bendline information may be utilized in the folding and
unfolding process of the invention. By performing a three dimensional rotation around
each bendline during folding or unfolding, the resultant 3-D or 2-D model may be
derived. This task may be accomplished by simply applying matrix transformation,
involving rotations and translations, to each of the faces and other entities of the part.
The features of various commercially available unfolding and folding software
applications may be utilized to implement these basic unfolding or folding steps ofthe
invention. For example, the Amada UNFOLD and FOLD system software may be
utilized to perform these basic operations. The Amada UNFOLD and FOLD system
software is available from Amada America, Inc. (previously operating under the coφorate name of U.S. Amada Ltd.), Buena Park, California. Information concerning
the Amada UNFOLD and FOLD system software may be found in the Amada UNFOLD
Manual for AUTOCAD (March 1994 Edition), the Amada UNFOLD Manual for
CADKEY (May 1994 Edition), and the Amada Windows UNFOLD Manual for
CADKEY (November 1995 Edition), the disclosures of which are expressly incoφorated
herein by reference in their entireties. Further discussion of the folding process to
develop the 3-D model from the 2-D model is provided below with reference to step
S.132.
Referring back to Fig. 8, after the bendline detection operation has been performed at step S.126, server module 32 may prompt the user for pertinent bend and
deduction information for subsequent use during the folding process. For example, at
step S.128, server module 32 may prompt the user to indicate the bend amount for each
bend line, including the bend angle and/or bend inside radius, as well as the bend
direction (e.g., front or back, etc.). At step S.130, the user may also be prompted by the
server module 32 to enter the V-width, material type, and/or the deduction amount. This
information may be utilized to compensate for bend deduction during the folding process.
Depending upon the thickness and type of material used for the sheet metal part, as well
as the angle ofthe bend and the V-width ofthe die to be utilized, the actual sheet metal
part will tend to stretch by a deduction amount during folding ofthe sheet metal part.
In order to compensate for this effect in the model, the deduction amount
information may be utilized so that the dimensions ofthe faces ofthe part are stretched
by half of the deduction amount on each side ofthe bending line when constructing the
3-D model through the folding process. In accordance with an aspect of the present
invention, this deduction amount may be entered directly by the user at the server module
32 (e.g., by keyboard, etc.). Altematively, a material table may be displayed to the
operator that includes the deduction amounts based on the material type and thickness of
the part. The material table may indicate the various deduction amounts based on
different bend angles and V-widths. The user may then automatically set the deduction
amount by selecting a desired V-width and bend angle from the material table displayed
at the server module 32 (e.g., by mouse or keyboard). The inside radius ofthe bend angle
may also be automatically set by the user through the material table when selecting a desired V-width. The deduction amount entered by the operator may be in (or converted after entry
by the operator to) a unit measure of length (e.g., mm) that is identical to that represented
by the part geometry data. During a folding process, the dimensional length of each of
the faces on either side of the bendline may be increased by one-half of the deduction
amount entered for that particular bendline. The dimensional length of the face that is
peφendicuiar to the bendline may be increased by extending the endpoints ofthe entities
defining the boundaries of the faces that are located on either side of the bendline. Such
deduction compensation may also be performed at each ofthe other bendlines of the part
based on the deduction amount provided by the operator for each bend.
In step S.132, a folding process is performed with deduction compensation to
develop the 3-D model based on the processed 2-D, flat drawing. As noted above, the
folding procedure may be carried out by conventional geometric modeling methods,
including the use of matrix transformation and using each of the respective bendlines
defined in the final bend graph data stmcture as a rotational axis. In addition, in order
to compensate for the effect of deduction, when folding and developing the 3-D model,
the faces ofthe part may be stretched by half of the deduction amount on each side ofthe
bendline to more accurately reflect the change in the dimensions ofthe faces when actual
bending ofthe sheet metal is performed.
For example, when performing the folding process at step S.132, the part
geometry and topology data (or bend graph stmcture) may be utilized, along with the
bend parameters (e.g., bend angle, inside radius, etc.). A transformation matrix may be
computed for each face, bendline, hole and forming in the part represented in 2-D space.
Conventional matrix transformation may be applied to the 2-D flat data to get the 3-D space data. The transformation generally involves a rotation followed by a translation.
As noted above, rotation is performed about each bendline axis in accordance with bend
angle amount. Translations are performed for shifting and moving the geometrical data
about space. Such translations may be determined based on the bending radius, bending
angle and deduction amount for each bend. During folding, deduction compensation is
performed so as to stretch or increase the dimensions of the faces by one-half of the
deduction amount on either side of the bendline, as described above. Such deduction
compensation will provide a 3-D representation of the part that more accurately reflects
the dimensions ofthe 2-D sheet metal part when it is folded by bending machinery.
For further information on geometrical modeling and transformations, see, for
example, MORTENSON, Michael M., Geometric Modeling. John Wiley & Sons, New York ( 1988) and FOLEY et al., James, The Systems Programming Series: Fundamentals
of Interactive Computer Graphics. Addison-Wesley Publishing Company, Reading,
Massachusetts (1983), the disclosures of which are expressly incoφorated herein by
reference in their entireties. Chapter 8 of MORTENSON provides a discussion of geometrical transformations, including translations and rotations (see, e.g., pp.345-354).
Further, FOLEY et al. at Chapter 7, pp. 245-265 provides information on geometrical
transformations, including matrix representation of 2-D and 3-D transformations.
Additional information of modeling and geometrical transformations may also be found
in MANTYLA.Martti. An Introductionto Solid Modeling. Computer Science Press, Inc.,
Rockville, Maryland (1988), the disclosure of which is expressly incoφorated herein by
reference in its entirety. Information on coordinate transformations may be found at pp. 365-367 of MANTYLA. Referringnow to Fig. 12, a description ofthe processes and operations that may
be performed for developing a 2-D model based on an original 3-D, flat drawing (with
no thickness) will be provided, in accordance with another aspect of the present
invention. Similar to the folding process described above with reference to Fig. 8, the
various processes and operations for unfolding a 3-D drawing and developing a resultant
2-D model may be implemented through the software and/or programmed logic at server
module 32. As shown in Fig. 12 at step S.140, the original 3-D, flat drawing which was
provided or developed based on the customer's specification may be entered or imported
into server module 32. The 3-D drawing may be stored as a DXF or IGES file and may be entered by interfacing with or utilizing a CAD or CAD/CAM system from server
module 32. After entering the 3-D drawing, an auto-trimming and cleanup operationmay
be performed at step S.142 by server module 32 to prepare the drawing for subsequent
face detection and other processing. As discussed above with reference to Figs. 9A-9E,
the auto-trimming and cleanup functions may break and connect entities and surfaces so
that the various faces of the part may be properly detected and defined.
The auto-trimming and cleanup operation described above with reference to Figs.
8 and 9 may similarly be applied to the geometric data o the 3-D drawing entered at step
S.140 of Fig. 12. Instead of analyzing the data in 2-D space (as was the case with the 2-D
flat drawing), each ofthe entities (e.g., lines, arcs, etc.) represented in the 3-D drawing
may be analyzed based on the 3-D coordinate and space information provided therein.
The intersection points and open intersection areas may be detected by analyzing each
entity individually and comparing it with other entities one at a time. Once again, basic
geometrical analysis ofthe endpoints and other attributes of the entities may be utilized to determine intersection points and open intersection areas within tolerance.
After performing auto-trimming and cleanup functions on the 3-D drawing, at
step S.144 a face detection operation may be performed to detect and define each ofthe
faces ofthe sheet metal part. Face detection for the 3-D drawing may be performed by
analyzing and detecting each ofthe faces in 2-D space and developing a loop tree, similar
to that described above. Face detection may be executed by starting at any predetermined
entity. For example, the left most entity (i.e., the entity with the lowest X-coordinate)
may be used as the initial entity. Thereafter, a plane may be defined by taking the initial
line entity and another connecting or adjacent line entity (e.g., any entity with a common
endpoint to the initial entity). A face detection operation may then be performed using
loop and entity analysis, such as that described above with respect to Figs. 10A- 1 OH. As each entity is detected within the defined 2-D plane, the various outside and inside loops
may be defined and the entities may be marked (e.g., by setting or incrementing a flag
ofthe selected entity) to indicate that they have been selected and included in a linked list
defining one ofthe loops in that plane.
Subsequent loop analysis may then be performed in the other 2-D planes that
comprise the 3-D drawing. In order to proceed with loop analysis ofthe other entities,
additional planes may be defined by searching for unmarked or unselected entities within
the 3-D drawing. Such planes may be defined between two unselected entities or an
unselected entity and a previously selected entity that was previously analyzed. In each
ofthe additional 2-D planes, further loop analysis may be performed to detect the inside
and outside loops. Once again, linked lists of connecting entities may be maintained and
the selected entities marked (e.g., by incrementing a flag associated with the selected entity) as each ofthe loop paths are defined.
After all of the entities have been detected, the resulting loops may be used to
develop a loop tree for each ofthe 2-D planes that were analyzed. As discussed above,
a loop tree may be provided to determine the faces and opening or holes in the sheet
metal part. For a 3-D drawing, a loop tree may be developed for each ofthe planes ofthe
sheet metal part. The loops detected within each plane may be grouped and analyzed to
develop each loop tree. The root of each tree may be defined as the outside loop detected
in the plane, with each inside loop of that plane that has a common entity with the outside
loop being defined as children of the root. The presence of common entities may be
detected based on analyzing and comparing the linked list of entities that define each
loop. If additional entities (e.g., holes or openings) are detected within the inside loops
of the plane, then these loops may be defined as children of the inside loops (i.e., the
grandchildren of the root ofthe loop tree) within which they are located. The generated
loop trees may then be used to detect all ofthe faces ofthe 3-D drawing. The detected
faces may then be stored as nodes in a bend graph data stmcture.
The resultant bend graph stmcture may then be supplemented with the connecting
bending line connecting agents after performing a bendline detection operation at step
S.146. The bendline detection operation and the development of the final bend graph
stmcture or part topology may be carried out in a similar manner to that described above
with reference to Figs. 1 1 A and 11 B.
As discussed above, an exemplary code for implementing the bendline detection
operation is provided in Appendix C attached hereto. The sample code is an exemplary implementation for the bendline detection operation that may be performed on a 2-D or 3-D model, and includes heuristics (such as those described above) for determining the
optimum selection of bendlines. The bendline detection operation may include a manual
selection feature to permit the operator at the server module 32 to selectively indicate the
preferred bendlines for the sheet metal part if not satisfied with the bendlines that were
detected. The operator may indicate to keep or change a bendline by any suitable input
means, such as a mouse or keyboard, etc. The revised bendlines selected by the operator
may then be used for developing the final 2-D part.
Before performing an unfolding process about the bending lines ofthe final bend
graph structure, the user may be prompted for the V-width, material type and or
deduction amount at step S.148. As discussed above, since metal tends to stretch when
it is folded, the dimensions of the 3-D part will be slightly larger than that ofthe 2-D flat
part. As such, during unfolding of the sheet metal part, the dimensions of the part should
be shrunk or reduced by the deduction amount based on the material type and V-width
selected. Accordingly, in accordance with an aspect ofthe present invention, a shrinking
process may be performed when unfolding the 3-D model to more accurately develop the
2-D model and the respective dimensions of its surfaces. As described above, the
deduction amount may be entered directly by the user or a material table may be
displayed in order to enable the user to automatically set the deduction amount by
selecting a desired V-width and bend angle.
The deduction amount entered by the operator may be in (or converted after entry
by the operator to) an unit measure of length (e.g., mm) that is identical to that
represented by the part geometry data. During an unfolding process, the dimensional
length of each of the faces on either side of the bendline may be decreased by one-half - 98 - of the deduction amount entered for that particular bendline. The dimensional length of
the face that is peφendicuiar to the bendline may be decreased by reducing the endpoints
ofthe entities defining the boundaries ofthe faces that are located on either side ofthe
bendline. Such deduction compensation may also be performed at each of the other
bendlines of the part based on the deduction amount provided by the operator for each
bend.
After entry of all of the necessary data, an unfolding process may be performed
at step S.150 to develop the 2-D model. Conventional methods may be used for
unfolding the 3-D bend model, including the use of matrix transformation with each of
the bending lines being used as a rotational axis. During the unfolding process, each of
the bend angles may be measured and the part may be unfolded by the bend angle amount to develop the flat 2-D model. In addition, based on the deduction amount entered, a
shrinking or reduction of the dimensions of the faces may be performed by half of the
deduction amount on each side of the bending line to more accurately simulate the
physical characteristics of the sheet metal material and the difference between the 3-D
and 2-D models.
When performing the unfolding process at step S.150, the part geometry and
topology data (or bend graph stmcture) may be utilized, along with the bend parameters
(e.g., bend angle, inside radius, etc.). A transformation matrix may be computed for each
face, bendline, hole and forming in the part represented in 3-D space. Conventional
matrix transformation may be applied to the 3-D data to get the 2-D space data. The
transformation generally involves a rotation followed by a translation. As noted above, rotation is performed about each bendline axis in accordance with bend angle amount. For unfolding, rotation is carried out in the reverse direction until there is a 180 degree
angle between the two faces (i.e., until the part is flat). Translations are performed for
shifting and moving the geometrical data about space. Such translations may be
determined based on the bending radius, bending angle and deduction amount for each
bend. During unfolding, deduction compensation is performed so as to shrink or
decrease the dimensions of the faces by one-half of the deduction amount on either side ofthe bendline, as described above. Such deduction compensation will provide a 2-D
representation of the part that more accurately reflects the dimensions ofthe sheet metal
part before it is folded during a bending operation.
Once again, further information on geometrical modeling and transformations
may be found in MORTENSON, FOLEY et al. and MANTYLA. As indicated above,
Chapter 8 of MORTENSON provides a discussion of geometrical transformations,
including translations and rotations (see, e.g., pp. 345-354). Further, FOLEY et al. at
Chapter 7, pp. 245-265 provides information on geometrical transformations, including
matrix representation of 2-D and 3-D transformations. In addition, information on
coordinate transformations may be found at pp. 365-367 of MANTYLA.
As discussed above with reference to Fig. 3, if a 2-D, three view drawing or a 3-
D, wire frame drawing with thickness is originally provided or developed based upon the
customer's order, then further processing will be required in order to develop a 3-D model
without thickness; and, thereafter, the developed 3-D model without thickness may be
used to create a 2-D model by applying an unfolding process or algorithm. Figs. 13-15 illustrate the various processes and operations that may be applied in order to develop a
3-D model based on an original 2-D, three view drawing. Further, Fig. 16 illustrates, in accordance with another aspect of the present invention, the additional processes and
operations that may be applied for developing a 3-D model without thickness from an
original 3-D, wire frame drawing with thickness. Once again, the various processes and
operations depicted in Figs. 13-16 may be implemented through the software and/or
programmed logic residing at, for example, server module 32.
Referring now to Fig. 13, a description of the logic flow of the operations and
processes that may be performed in order to develop a 3-D model (with no thickness)
based on an original 2-D. three view drawing will be provided, in accordance with the
teachings of the invention. Initially, the 2-D, three view drawing may be entered or
imported to server module 32 at step S.160. The original 2-D, three view drawing may
comprise various views ofthe part (e.g., a front view, a top view and a right side view -
see, e.g., Figs. 14B and 14C) and may be a CAD drawing such as a DXF or IGES file that
may be downloaded or imported to server module 32. Thereafter, at step S.162, a 2-D
cleanup operation may be performed by server module 32 in order to prepare the drawing
for subsequent processing into the 3-D model. The 2-D cleanup operation may be performed in order to eliminate extraneous and non-geometrical information, including
text, centerlinesand dimension lines, which do not represent the actual geometry of the
part. The 2-D cleanup operation may also be performed in order to connect all exterior
lines at, for example, their connecting ends and to break and trim any intersecting lines
or entities. Fig. 14A illustrates an example ofthe logic flow ofthe various processes that
may be carried out when the 2-D cleanup operation is performed by server module 32.
As shown in Fig. 14A, the 2-D drawing is first read from a data file or loaded at step S.180 by server module 32. Thereafter, at step S.182, server module 32 may analyze the respective entities and geometrical data in the 2-D drawing and break the various
entities in order to prepare the drawing for further processing. The break and trimming
function performed at step S.182 may be carried out in a similar manner to that described
above with respect to the auto-trimming and cleanup function of the present invention.
Thus, at step S.182, all of the geometrical data in the 2-D, three view drawing may be
analyzed in order to detect the intersection of entities and any open intersections that are
within tolerance. Any intersecting lines may be broken, with the resultant entities
meeting at a common endpoint defined by the intersection point. Further, for entities
having an open intersection area that is within a predetermined tolerance (e.g., 0.0 - 0.01
mm or 0.0 - 0.001 inches), such entities may be joined, in a similar manner to that
described above with respect to, for example, Fig. 9E.
At step S.184, the perimeter of the 2-D drawing sheet may be detected and any
exterior lines or data (such as border lines, coordinate grids and numbers, etc.) may be
eliminated. As shown in Fig. 14B, a 2-D, three view drawing will often be provided on
a drawing sheet. The drawing sheet may include extraneous and non-geometrical
information that is not necessary to process the views of the sheet metal part. As such,
during step S.184. this type of information may be detected and eliminated from the 2-D
drawing when developing the 3-D model utilizing the 2-D clean-up process of the
invention.
The 2-D drawing data may include key words or type fields to indicate the type
of data contained therein (e.g., geometrical or non-geometrical/text). Thus, these key
words or type fields, which are provided based on the data format of the drawing file,
may be used to eliminate various extraneous information, such as text and other non- geometrical data. However, further processing is usually necessary in order to properly
eliminate all of the unwanted drawing sheet data. Often, the border lines and other
outside information are saved as entities (e.g., lines, etc.) that can not easily be
distinguished based on the data key words or type fields. As such, according to an aspect
ofthe present invention, a connectivity graph stmcture may be developed when analyzing
the data of the 2-D drawing. The connectivity graph stmcture may indicate for each
entity a list of incident vertices and a list of connected entities. For each vertex, a list of
adjacent vertices and a list of entities on which it is incident may also be provided. With
this graph stmcture, which may be developed when performing the break and trimming
function of step S.182, it may be determined which entities are connected by matching
endpoints. As a result, extraneous data, such as as border lines, information boxes and
other non-geometrical data, may be eliminated since this data will typically not be
constmcted with or include connecting entities.
As noted above, the 2-D, three view drawing may include extraneous information,
such as dimension lines, arrow lines, centerlines, and text, which do not represent the
actual geometry of the part. These entities may be detected at step S.186 and deleted
from the 2-D data file in order to prepare the 2-D drawing for further processing. The
detection of these extraneous entities may be performed automatically by server module
32 (e.g., by detecting items in the 2-D data file that do not relate to the actual geometry
of the part). For example, by using the connectivity data graph stmcture, two-sided
opened entities (e.g., lines used for underlining text or to indicate a dimension or
centerline in the part) may be detected and eliminated. Other entities, such as arrows, may also be detected based on the presence of floating endpoints and other characteristics of such entities. In order to effectively eliminate all unnecessary data, the server module
32 may also provide a manual editing function to permit an operator to indicate (e.g., by
mouse or keyboard) which items in the 2-D drawing should be eliminated. Through the
assistance or confirmation of he operator, additional extraneous information may thus
also be removed from the drawing.
After step S.186, the various views in the 2-D drawing may be grouped and then
respectively defined at step S.188. In accordance with an aspect ofthe present invention
server module 32 may support predefined or standard views and orientations, such as a
top view, front view, right side view layout, such as that shown in Figs. 14C and 14D.
Other views and layouts, such as combinations of a top view, a front or back view, and a right or left view, may also be supported. As further described below, server module
32 may also support rotated views (see, for example, Fig. 14D) in order to process the
views in the 2-D drawing into the 3-D representation of the part. In any event, at least
two (and preferably three) different views of the part with thickness representations
should be provided so that a 3-D model ofthe part may be constmcted. By analyzing the
connectivity and grouping of the entities in the connectivity graph stmcture, server
module 32 may group and define the views based on the relative position and/or
coordinate location of each ofthe views.
By way of a non-limiting example, the definition ofthe views by server module
32 may be carried out in accordance with a predefined or customary arrangement or
layout for analyzing the views in the data file, and/or based upon detecting the orientation of the views and matching the various dimensions of the part in each of the respective
views in the drawing. A predefined or canonical form, such as that shown in Fig. 14E, may be used to determine and define each ofthe views according to possible view types.
Geometric comparisons ofthe various endpoints and relationships between the entities
defining each group may be performed in order to effectuate step S.188. The view
detection feature of server module 32 may label each of the views according to one of
plurality of possible view types (e.g., top view, front view, back view, left view, right
view). The detection of each of the views may be based on a predefined or canonical
view layout or form, and based on the detected relationships between each ofthe views
that are present.
Various processes and operations may be used at step S.188 to group and define
the views in the 2-D, three view drawing. For example, after accessing the processed 2-
D, three view drawing, the server module 32 may first identify the top view ofthe part in the drawing data. The top view may be detected based on the predefined or canonical
form, view layout (such as that in Fig. 14E). If three separate views are detected in either
a horizontal or vertical direction, then the center view may be defined as the top view.
Further, if three separate views are not detected, and only two separate views are detected
in a vertical direction, then the upper view may be defined as the top view. Once again,
the connectivity and grouping ofthe entities in the connectivity graph stmcture may be
utilized to detect each of the views. A stored lookup table or matrix representing the
predefined or canonical form may be used to compare the views of the 2-D drawing and
detect each of the views.
After detecting the top view from the 2-D, three view drawing data, the other
views of the part may be detected based on the relative position of each ofthe views to the detected top view. For example, based on the canonical view layout of Fig. 14E, if a view grouping is located above the top view, then the view may be defined as a back
view. If, however, a view grouping is located below the top view, then the view may be
defined as a front view ofthe part. Further, a right view and a left view may be detected
based on their relative position on the corresponding right hand side and left hand side,
respectively, ofthe top view. Thereafter, any remaining views, which do not conform
to the canonical form (such as Fig. 14E), may be detected based on their relative position
to the detected views (e.g., a detected back view or front view). For example, for the
layout B shown in Fig. 14D, the right view has been provided in a rotated position
relative to the top view. The right view in layout B, however, may still be detected based
on its relation to the detected front view. That is, undetected views that are present on
the right hand side or left hand side of a detected back or front view may be defined,
respectively, as a right view or a left view ofthe part.
Various predefined or canonical view layouts may be used to detect and define
views in the 2-D. three view drawing. The canoncial forms (such as that in Fig. 14C or
Fig. 14D) may be selected based on the numbers of view types that are to be supported
and/or based on the view layouts that are more prevalent or selected required by the
manufacturing facility. If any views are not detected, a warning signal may be provided
by the server module so that an operator may modify the 2-D, three view drawing data
in accordance with the preferred view layout, or take other appropriate action. In addition
to providing a predefined or canonical form for detecting the views in the 2-D drawing,
a predefined or canonical form (such as layout A in Fig. 14D) may also be provided for
processing the detected views and developing the 3-D model of the part. As such, a rotated view feature may be provide to properly group the detected views in accordance with the canonical form before further processing is performed.
As mentioned above, the 2-D cleanup operation may support and detect rotated
views which do not conform to the predefined or canonical form for detecting views in
a drawing. With the rotated view option, non-conforming views that have been detected
may be rotated or translated so that each of the views conform to the predefined or canonical view form for processing and developing the 3-D model ofthe part. Assuming
a canonical form such as that illustrated in Fig. 14E for detecting views of the part, each
ofthe views in layout B in Fig. 14D may be detected based on the relative position ofthe
views to the top view and the other detected views, as described above. If, for example, the layout A in Fig. 14D is to be used as a predefined or canonical view layout for
processing the various views in a 2-D drawing having a top view, front view and a right
view, then at step S.188 the right view in layout B may be rotated by 90 degrees to
provide a modified view layout for the part that is similar to layout A. By rotating the
right view in layout B by 90 degrees so that the right view of the part is provided on the
right side of the top view of the part, the views in the drawing may be processed in
accordance with the canonical form represented by layout A. A stored lookup table or
matrix representing the predefined or canonical form may be used to compare the views
ofthe 2-D drawing and to determine which views require rotation and translation.
In order to ensure that an accurate 3-D model ofthe part is developed from the
views in the 2-D drawing, the respective dimensions in each of the views should be
checked for consistency and matching. As further shown in Fig. 14A, at step S.190,
the boundaries ofthe views in the data file may be detected in order to confirm that all of the dimensions of the respective views are in scale with one another. If it is determinedthat the views do not match within a predetermined tolerance (e.g., 0.0 - 0.01
inches), then appropriate modification may be made at step S.190 to redimension any
particular view in order to ensure that all ofthe views are provided in the same scale. A
warning component may be provided in server module 32 to alert a user that the view
dimensions do not match so that the necessary modifications can be made to the 2-D
drawing data that is present.
Various operations and processes may be utilized to detect and verify the
consistency of the dimensions in the respective views of the part. For example, the
corresponding dimensions of each of the views may be compared to determine if they are
within a predetermined tolerance of one another. Such an analysis may include
comparing the line entities that define the boundaries of each view ofthe part. Assuming the canonical form in Fig. 14E, a top view may be detected as matching a right view or
a left view if the difference, for each view, between a maximal Y coordinate position and
a minimal Y coordinate position is within a predetermined tolerance (e.g., 0.0 - 0.01
inches). Further, the top view may be detected as matching a front view or a back view
if the difference, for each view, between a maximal X coordinate position and a minimal
X coordinate position is within a predetermined tolerance (e.g., 0.0 - 0.01 inches).
Moreover, the left view or right view may be determined as matching a front view or a
back view if the difference between a maximal X coordinate position and a minimal X
coordinate position compared to the difference between a maximal Y coordinate postion
and a minimal Y coordinate position is within a predetermined tolerance (e.g., 0.0 - 0.01
inches). Once again, a warning component or module may be provided in server module
32 to alert a user when the view dimensions or related face dimensions do not match so that the necessary modifications can be made to the 2-D drawing data that is present.
Finally, at step S.192, the inside loops, holes and shapes of the part may be
detected in accordance with the teachings ofthe face detection procedure ofthe present
invention. The various holes and shapes provided on the interior of the faces of each
view may be detected by looping through the various lines and boundaries of the part
from the exterior of the part towards the center. Loop and entity analysis may be
performed on each view ofthe part in the 2-D drawing. By analyzing each view from the
outside and working inwardly towards the center of the part, the detected loops will
define the boundaries and areas of the material and openings of the part based upon a cyclic sequence (e.g., material, opening, material, etc.). A loop tree, such as that in Fig.
10H, may be developed for each view to determine the location of the faces and any
openings within each face. Unconnected entities, such as floating arcs or lines, within
the faces of the part may also be detected and eliminated during step S.192.
An exemplary code for performing the 2-D clean-up operation of the present
invention is provided in Appendix D. The code was written in C++ programming
language and includes comments to facilitate the analysis of the logic and algorithms
used therein. The code includes the various processes and operations ofthe 2-D clean-up
mode, such as those discussed above with reference to Figs. 14A-14C.
Referring back to Fig. 13, after a 2-D clean-up operation has been performed,
logic flow will then continue to step S.164 where it may be determined whether the 2-D
drawing represents or includes the thickness of the material (i.e., whether the 2-D
drawing is with thickness). If the 2-D drawing is determined to contain the thickness
amount, then at step S.166, an eliminate thickness procedure may be performed by server module 32 in order to prepare the 2-D drawing for subsequent processing into a 3-D
model. The determination of the existence of thickness in the 2-D drawing may be
performed automatically by server module 32 based on the data ofthe drawing, or may
be performed by the server module through the assistance or response from the operator
(e-g-, the operator may be prompted to indicate whether thickness removal is necessary
or desired). The thickness ofthe part may be eliminated due to the unique symmetry of
all sheet metal parts. By eliminating the thickness ofthe part, the resultant sheet metal part with no thickness may be more easily analyzed by a sheet metal operator or designer.
Further, the inventors of the present application have found that by eliminating the
thickness of the 2-D, three view drawing, the time required to convert the 2-D drawing
and develop the 3-D model may be substantially reduced.
Since most 2-D, three view drawings include a material thickness amount, an
operator may often be confused by which bend lines should be selected in order to make
a 3-D model from the 2-D drawing. As a result, considerable time is wasted in selecting
the appropriate bend lines so that the 2-D, three view drawing may be converted into a
3-D model. An example of a three view, 2-D drawing with thickness is shown in Fig.
15 A. According to an aspect of the present invention, an eliminate thickness procedure
may be provided to display a simplified 2-D, three view drawing model which is
represented and processed with no material thickness, but retains the material thickness
amount and the inside or outside dimensions ofthe part in the bend model data. Fig. 15B
illustrates the simplified three view, 2-D drawing that may be viewed and displayed to
the operator at server module 32 after performing the eliminate thickness procedure.
When the eliminate thickness procedure is executed, the user may be prompted to specify the material thickness in the 2-D, three view display, and may be prompted to
specify which dimension (i.e., the outside dimension or inside dimension) is to be
retained in the display. The operator may indicate the thickness and surface to retain in
one of the views by use of, for example, a mouse. Based upon the data entered by the
user, server module 32 may modify the 2-D, three view drawing to eliminate the material
thickness indicated by the user and to retain the inside or outside dimension based on the
operator's selection.
In order to eliminate the thickness in the 2-D, three view drawing, the server
module 32 may analyze each of the three views based on the selections made by the
operator. The selected surface may be projected into each of the other views by
geometrical computations (e.g., by detecting the corresponding entities that lie in the
same X-coordinate or Y-coordinate projection as the selected entity line or surface) to detect the corresponding entities and lines in each of the views. The corresponding
entities may be marked and retained, with the nonmatching entities or surfaces being
eliminated or not displayed on the screen, such as that shown in Fig. 15B. Further, the
thickness dimension line indicated by the operator may be similarly projected into each
of the other views, with the matching thickness dimension lines or entities being
eliminated, as further shown in the example if Fig. 15B. As a result, each ofthe views
in the drawing may appropriately modified and then displayed to the user at the server
module 32. The resultant 2-D, three drawing with no thickness may also be used for
subsequent processing in order to develop the 3-D model of the part.
The thickness elimination procedure of the present invention may include a
manual thickness elimination mode to permit an operator to selectively indicate in each - i ll - view the thickness lines to be eliminated and the surface entities to be retained. A mouse
or other appropriate input device may be used by the operator to indicate which areas in
each ofthe displayed views are to be eliminated and which surfaces are to be retained.
Based on the data entered by the operator, the server module 32 may eliminate each line
entity selected by the operator from the 2-D, three view drawing in order to provide a
drawing with no thickness.
The present invention may also include a warning system or module to analyze
and detect whether all the thickness representations have been properly identified in the
2-D, three view drawing, and to alert the user when there are unmarked thickness
components and or when there are inconsistencies in the drawing data. For example, a
thickness warning component may be provided to highlight on the display screen
possible unmarked thickness segments, and a face warning component may be provided
to highlight on the screen possible mismatched faces when the face dimension does not
match the thickness mark in another view. A bendline warning component may also be
provided to highlight inconsistent bendlines and highlight mismatching thickness arcs.
An arc may be highlighted when at least one bendline projected on this arc is not bound
by two cross thickness lines. For instance, Fig. 15C illustrates a thickness arc that is
properly bounded by two or another non-zero even number of cross-thickness lines (i.e.,
a small line crossing the thickness in one ofthe views). Each bendline should also be
bound by two or another non-zero even number of cross-thickness lines. The analysis
of these entities ofthe part in each view may be based on performing a loop analysis on and analyzing the connectivity ofthe line and arc entities that make-up each view. An
open thickness line may be defined based on a thickness line that has at least one end point that is not connected to another thickness line or arc. A side that includes an open
thickness line may be defined as an open thickness side. A thickness line may be
highlighted if the open thickness side of an open thickness line does not match the
bounding box of a minimal loop. By providing such warnings relating to the processed
2-D, three view image to a user, the user may be alerted of inconsistenciesin the drawing
data, and the user will thus be able to modify and/or correct the drawing data before
further processing is performed to develop the 3-D model of the part. Inclusion of such
a warning system and user interaction also improves the accuracy of the representation
ofthe part by the 3-D model.
At step S.168 in Fig. 13, the processed 2-D, three view drawing with no material
thickness may then be converted and developed into a 3-D model. The conversion and
development of the 3-D model from the 2-D, three view drawing may be performed by
using well-known or established projection and/or extrusion methods. For example, in
order to develop the 3-D model from the three view, 2-D drawing, the depths of each of
the views may be detected and then each ofthe views projected in order to develop a 3-D model. The resultant 3-D model may then be used when developing the bend model data
and also converted into a single view, 2-D flat drawing by applying the above-described
unfolding algorithm. For more information geometric modeling techniques, see
MORTENSON, FOLEY et al. and MANTYLA. For additional information on
projection techniques to constmct 3-D models from 2-D drawings, see, for example,
WESLEY et al., W.A., Fleshing Out Projections. IBM J, Res. Develop., Vol. 25, No. 6,
p.934-954 (1981); AOMURA, Shigeru, Creating Solid Model with Machine Drawings.
The 6th Computational Mechanics Conference, JSME, No. 930-71, Japan, pp. 497-98 (1993); and AOMURA, Shige , Recent Trends and Future Prospect of Research and
Practical Use (Automatic Reconstructionof 3D Solid from Drawings). Toyo Engineering
Coφ., Japan, pp. 6-13 (1995); the disclosures of which are expressly incoφorated herein
by reference in their entireties.
When developing the 3-D model at step S.168, an additional clean-up process
may be included in order to further process and refine the resultant 3-D model. In
accordance with an aspect of the invention, a 3-D clean-up process may be provided to
compensate for ambiguities that are present in the 2-D, three view drawing ofthe part and
that create extraneous or superfluous information in the developed 3-D representation of
the part. As will be appreciated by those skilled in the art, a 2-D, three view
representation of a part includes ambiguities concerning the representations of various
features ofthe part in 3-D coordinate space. When developing the 3-D model from the
three view, 2-D drawing, extraneous and superfluous information may be generated as
a result of these ambiguities. As such, according to an aspect of the invention, the 3-D
clean-up process may include processes and operations for detecting and removing one
sided open lines and for detecting and cleaning bendlines and trimming faces. The 3-D
clean-up process may be performed automatically when developing the resultant 3-D
model ofthe part, or may be selectively performed based on input from an operator when
the developed 3-D model is determined to require further processing.
According to the 3-D clean-up process, by analyzing the developed 3-D drawing
data, every line or arc which is determined to be not connected to another entity at one
of its endpoints may be identified and defined as a one sided open line. Any entity that
is determined to be a one sided open line may be removed from the 3-D representation of the part. Once an open line is removed, it may cause another line or entity to be open.
As such, new one sided open lines are also identified and removed recursively until all
open lines or entities are removed. Fig. 49A illustrates an example of a 3-D
representation of a part before one sided open lines are removed, and Fig. 49B illustrates
the part after the one sided open lines have been removed from the 3-D representation.
As noted above, the 3-D clean-up process that may be performed at step S.168
may also include a process for detecting and cleaning bendlines. Bendlines may be
identified and cleaned (e.g., by adding mold lines) in order to facilitate the detection of
face information of the part in 3-D space. Based on the developed 3-D model data, each
bendline may be identified based on the detection of a pair of 3-D arcs (e.g., represented
by arc entities in the drawing data) which have the same normal defined by their centers. During this process, mold lines may be added to the bendlines that are identified. The
mold lines may be added by identifying corresponding endpoints in each pair of 3-D arcs,
and extending mold lines (e.g., represented by line entities) between the corresponding
endpoints of the 3-D arcs. Fig. 50A illustrates an exemplary 3-D representation of a part
before the bendlines have been identified, and Fig. 50B illustrates the part after the mold
lines (represented by dashed lines in the drawing) have been added.
After the bendlines have been identified and the mold lines have been added, the
3-D clean-up process may further process the 3-D representation ofthe part to further
clean all bendlines and trim the faces of the part. Due to frequent ambiguities in the
views of the 2-D, three view drawing data, superfluous sections of the faces may be
generated in the 3-D representation of the part. The 3-D clean-up process may identify these superfluous sections of the faces and trims the faces using sheet-metal domain knowledge (e.g., knowledge relating to what is unfoldable). Other extraneous
information, such as extra holes or openings, may also be identified and eliminated. As
a result, the superfluous sections ofthe part may be removed and the 3-D representation
may provide a more accurate representation of the sheet metal part. Fig. 51 A illustrates
an exemplary section of a part before cleaning the bendlines and trimming the faces, and
Fig. 5 IB shows the section ofthe part after cleaning and trimming has been performed.
Fig. 16 illustrates an example of the logic flow of the processes and operations
that may be performed in order to develop a 3-D drawing with no material thickness from
an original 3-D drawing with material thickness. At step S.200, the original 3-D drawing
with material thickness may be entered or imported to server module 32. The 3-D model
may be a 3-D, wire frame drawing with material thickness and may be a CAD drawing
file, such as a DXF or IGES file. After the 3-D drawing has been imported to the server
module 32, an eliminate thickness procedure may be performed at step S.204. The
eliminate thickness procedure at step S.204 on the 3-D model may be performed in a
similar manner to that provided in the Amada UNFOLD software system, described above. In order to eliminate the thickness in the 3-D model, the operator may first be
prompted to indicate the thickness and to select the surface to be retained. Based on the
operator's selection, the thickness is measured by analyzing the endpoints ofthe entity
line defining the thickness. Thereafter, the boundaries of the selected surface may be
traced, in a similar manner to that described above with respect to the loop and entity
analysis process, with the entities to be kept being marked (e.g., by setting or
incrementing a flag) and the corresponding thickness entities being eliminated. When tracing the entities ofthe 3-D part, the entities may be distinguished based on the length of the thickness entity selected by the user. Generally, all entities having the same length
ofthe thickness entity may not be selected and eliminated, with the other entities that are
not of the same length being marked and retained. Any remaining entities that are not
marked during the surface trace ofthe 3-D part may also be eliminated. Once again, the
server module 32 may provide a manual thickness removal mode, in which an operator
may manually indicate each entity in the 3-D part that is to be removed.
After step S.204, the resultant 3-D model with no material thickness may be
developed and or displayed to the operator at step S.206. An unfolding algorithm or
process may then be applied to the 3-D model with no material thickness to develop the single view, 2-D flat drawing for the bend model data, as described in greater detail
above.
As discussed above, the design and manufacturing information that is stored in
database 30 may include a bend model data file comprising part geometry and topology
as well as manufacturing data for the sheet metal component. Further, the software that
may be used to implement the various features ofthe invention may be developed using
a high level programming language such as C++ and by using object oriented
programmin techniques. Different object oriented techniques may be used, such as
Booch or OMT to implement the various features of the invention. If object oriented
programming is utilized, an object oriented data model may be utilized to represent the
sheet metal part and the bend model for the part may be implemented through a
completely self-contained class library. In accordance with an aspect of the present
invention, a description will now be provided of any exemplary data stmcture and access
algorithm for the bend model, based on object oriented programming techniques. Fig. 17 illustrates an exemplary data stmcture and access algorithm ofthe bend
model that may be utilized when implementing the present invention through object
oriented programming. Object oriented programming is a type or form of software
development that can model the real world by combining objects or modules that contain
data as well as instructions that work upon that data. In object oriented programming,
objects are software entities that may model something physical, like a sheet metal part,
or they may model something virtual, like business transactions. Objects may contain
one or more attributes (i.e., fields) that collectively define the state ofthe object, and may
contain an identity that distinguishes it from all other objects. In addition, objects may
include behavior that is defined by a set of methods (i.e., procedures) that can modify the
attributes or perform operations on the object based on the existence of certain
conditions.
According to an embodiment ofthe present invention, the sheet metal part may
be represented as an object oriented data model. As shown in Fig. 17. the bend model
for the sheet metal part may be defined as a completely self-contained class library. All
of the required data manipulation and functions for the sheet metal part (e.g., folding,
unfolding, etc.) may be captured as member functions of the class library. All of the
geometrical and topological data may be defined in objects that are grouped within the
bend model. The bend model class library may be a hierarchy of classes or objects with
a part class being the top level class in the hierarchy. The part class may include a part
object with various part attributes and may have various objects that define the part and
the actions that may be performed on or to the part.
Fig. 17 shows an example ofthe various objects that may be grouped in the bend model class library. For example, a part class 50 may be provided that includes various
attributes 52. The part attributes 52 may include various part information such as the part
number and/or name, the part material type and the thickness of the part. The attributes
52 may also include bend sequence information for indicating the order in which the
bends are to be performed and other manufacturing information such as tolerance
requirements for the various dimensions of the part. Part class 50 may also comprise
various objects, such as a faces object 54, a holes object 56, a formings object 58, and a
bendlines object 60, as shown in Fig. 17. Each of the objects 54, 56, 58 and 60 may
actually consist of a group of objects for each ofthe entities (e.g., faces, holes, formings,
and bendlines) represented therein. The faces object 54, holes object 56, formings object
58 and bendlines object 60 may each include geometry and dimension data, location and
coordinate data in both 2-D and 3-D space representations, and data relating to the edges
and surfaces of their respective entities (e.g., faces, holes, formings, and bendlines) of the
part. For example, the faces object 54 may include geometry and dimension data for each
of the faces, location space data of the faces in both 2-D and 3-D representation, and
edges and surface data for the edges and surfaces of the faces. In addition, the formings
object 58 may include data relating to special formings in the part, including geometry
and dimension data, 2-D and 3-D location space data, and edges and/or surfaces data.
As further shown in embodiment of Fig. 17, the part class 50 may also include a
topology object 62 and a bend properties object 64. The topology object 62 may include
the part topology data for the faces, holes, formings and bendlines of the part. The data
in the topology object 62 may indicate the stmcture and geometric relationships ofthe
various features of the part. The bend properties object 64 may also be provided and include information concerning special manufacturing constraints for one or more
features ofthe part. For example, bend properties information concerning how the sheet
metal part should be bent may be provided in the bend properties object 64. The bend
properties information may include specific manufacturing data for different bend
property types (e.g., simultaneous bend, colinear bend, Z-bend. etc.).
The bendlines object 60 may also include manufacturing specific data relating to
the bends to be performed. Thus, in addition to providing geometry and dimension data.
2-D and 3-D location space data, and edges data for each bendline, the bendlines object
60 may also include V-width data, bend pitch data, bend count data and/or orientation
data for each of the bendlines. Each of the bendlines may also include an associated
bending operation, as shown in Fig. 17. The bending operations may be implemented as
a group of objects with data and operations/instructions for performing bends at each
bendline. If provided as an object, each bending operation may include data and
instructions indicating how and what type of bending is be performed (e.g., conic bend,
Z-bending, Hemming, arc bending, etc.), as well as pertinent bend data such as the bend
angle, bend radius and/or bend deduction amount.
By implementing the bend model of the part through an object oriented data
model, all ofthe complex mathematical calculations, computational geometry and matrix
transformationsmay be built into a single class library. Special bending operations, such
as hemming, Z-bending and arc bending, may also be captured inside the class library.
Further, manufacturing information, such as the V-width, the bend deduction amount,
and the bend sequence, may be also captured within the class library. With the bend
model, simultaneous dual representation of both the 2-D flat model and 3-D model may be effectuated, as shown in Fig. 17. Further, bending operations may be performed in
accordance with the bend lines object 60 of the bend model. General comments
regarding the bend model and the part stmcture, as well as implementation ofthe same,
are provided in Appendix K attached hereto.
A bend model viewer may be provided to inteφret the bend model and display
visual images of the part in 2-D and/or 3-D space representation. Fig. 18 illustrates a
block diagram of the stmcture of the bend model viewer and its relation to the bend
model, in accordance with another aspect of the present invention. The bend model
viewer may be implemented through object oriented programming techniques and may
be a Windows based application that permits users at the station modules of the various
locations 10, 12. 14...20 in the facility 38 to display various views of the part based on the information provided in the bend model. The bend model viewer may comprise a set
of application library modules that are used to visualize the sheet metal part. Further, the
bend model viewer may be designed as a base view class ofthe Windows application so
that it can be used as a base view class for any Windows application. Most of the
standard operations to view the 2-D and 3-D models (e.g., zoom 92, rotate 96, pan 100,
dimension 102, etc.) may be implemented as member functions of the bend model
viewer. Geometric transformations and fundamental computer graphics techniques may
be applied to the bend model objects when performing viewing operations. In addition,
the bend model viewer may comprise view model attributes 88, that comprise, for
example, four major view modes including a solid view, a wire frame view, a 2-D flat
view and an orthographic view.
According to an aspect of the invention, the bend model class library 80 may includea set of procedures or functions that act upon sheet metal parts depending upon
the selected view (e.g., solid, wire, 2-D flat or orthographic view). The bend model
viewer view class 84 may comprise a series of standard operations, such as zoom 92,
rotation 96, pan 100 and dimension 102; and, depending upon the state ofthe bend model
viewer, the bend model viewer view class may call functions from the bend model class
library 80. As shown in Fig. 18, the various view model attributes or features 88 that
may be selected by a user may include a solid view, a wire frame view, a 2-D flat view
and an orthographic view. A brief description of these various view modes that may be
provided in the present invention is provided below with reference to Figs. 19-22.
Fundamental computer graphics and geometric modeling techniques, such as
geometric transformations and 3-D geometry techniques, may be utilized to implement
the various features of the bend model viewer and to provided the different viewing
modes and functions. Recent advancements and developments in computer-based 2-D and 3-D modeling and simulation, such as the availability of graphics libraries or
packages, may be applied to implement these features of the present invention. In
addition, a wide variety of publications and material are available regarding computer
graphics and modeling. See, for example, MORTENSON, FOLEY et al., and
MANTYLA, each of which is referenced above.
In order to provide the various viewing and modeling features of the present
invention, each station module and the server module may be provided with a high
resolution display screen, such as a SVGA screen with 800 x 600 resolution. A joystick
and game card may also be provided at the station module and server module to permit
the user to selectively modify and view the different 2-D and 3-D representations of the part. Software based graphics packages, such as OpenGL and RenderWare, may be used
to provide graphical computations. Such graphics librariesor packages may be Windows
based applications and can be used to render the various viewing modes. OpenGL, for
example, may be used to render the various 2-D wire frame views based on the part
geometry and topology data provided in the bend model. Further, Renderware may be
utilized to render the various 2-D and 3-D solid views of the sheet metal part based on
the part data provided in the bend model. For more information on OpenGL, see. for example, the OpenGL Reference Manual and the OpenGL Programming Guide. Release
1 , OpenGL Architecture Review Board, Addison-Wesley Publishing Company, Reading,
Massachusetts (1992). For information on RenderWare, see, for example, the
RenderWare API Reference Manual. V2.0, Criterion Software Ltd., United Kingdom
(1996).
In order to render the various views ofthe part, the bend model may be accessed
from the database 30 by, for example, the station module of the operator. The bend
model data may then be reformatted in accordance with the data format utilized by the
graphics library or package (e.g., OpenGL or RenderWare) that is utilized. Thereafter,
the graphics data may be processed in accordance with various programmed routines in
order to render the viewing mode (wire, solid, etc.) selected by the operator or perform
the viewing function (zoom, pan, etc.) executed by the user.
When a particular view mode is selected by an operator, the selected viewing
mode is detected along with the current zoom ratio or factor and orientation of the view.
This information is then used to make function calls to the graphics package to update the current display. Function calls to the graphics package may be made in accordance with the viewing mode to be rendered, as well as the zoom or other viewing function to
be performed. Based on these function calls, the graphics package provides the necessary
data so that the station module may render the view ofthe part to the operator. Based on
the modifications to the 2-D or 3-D representation by the user (e.g., by moving a joystick
or a mouse), additional function calls may be made to the graphics library to update the
rendered image.
To provide the wire frame views of the part, the line entity data ofthe part may
be provided to the graphics package to perform the necessary graphical computations.
With solid views, however, one or more polygons should be derived for each ofthe faces
and provided as input to the graphics package to render the view. Graphics packages
such as OpenGL and RenderWare will take as input polygonal data and fill in the areas
defined by the polygons to provide a solid image. Polygons may be derived from the
face and bendline information in the bend model and by determining the boundaries of
each face. Polygons should be created to present and define each face ofthe part. The
faces may then be connected, based on the part topology and other data in the bend
model, in order to render the overall sheet metal part. If a face contains an opening or
hole, then it will be necessary to define the face with several polygons that do not
encompass such openings. For orthographic views, data for each ofthe individual views
(which may be wire frame or solid) may be sent to the graphics package and the resultant
views combined on a single display screen, such as that further shown in Fig. 22.
An exemplary code for implementing the various viewing modes and functions
ofthe bend model view is provided in Appendix E. The sample code is written in C++
and includes comments relating to the processes and operations performed therein. The code in combination with an appropriate graphics package (such as OpenGL and
RenderWare) may not only be used to render the different views (e.g., 2-D and 3-D wire
frame or solid), but also provide the functionality of each of the viewing functions (e.g.,
zoom, rotate, pan, etc.). A brief description of the various viewing mode display screens
that may be rendered is provided below.
The solid view mode displays a solid rendered 3-D view of the part defined by
the bend model. Fig. 19 illustrates an exemplary solid view window that may be
provided as output to a display screen provided at any of the locations 10, 12, 14...20 within the sheet metal facility 38. In the solid view mode, the user or operator may be
provided with a plurality of viewing functions for manipulating 3-D space navigationand
3-D automatic dimensioning. The basic functions that may be provided for altering the
solid view of the part may include rotation, zooming, panning, and/or standard view
selections. The standard views that may be provided and selected by the user may
include the following: isometric, top, bottom, front, back, left and right. An automatic
or manual dimension operation may also be provided to display the critical dimensions
of the part based on the current viewing angle. An exemplary embodiment of the
dimension feature ofthe present invention is provided below with reference to Figs. 23-
27.
As shown in Fig. 19, the solid view window may be a Windows based
application; and, thus, multiple windows or sectional views ofthe part may be provided.
The multiple view windows may include a worm view that provides a very close-up
isolated view within a window, and a bird's eye view which provides a very far away
view of the part in an isolated window. The sectional view may provide a partial view of the object as selected by the user. In order to control the various viewing functions,
a joystick interface may be provided at the server module 32 and the station modules of
each of the locations 10, 12, 14...20. Operation of the joystick alone and/or in
combination with operation of certain keys on the keyboard (e.g., a shift key or control
key) may be performed by the user in order to carry out the various functions such as
rotating, panning and zooming. In addition, the displayed texture ofthe solid view ofthe
part may be selected in order to simulate the material specified for the part in the
database. For this purpose, a material texture library may be provided that comprises a
library of material textures, such as steel, stainless steel, aluminum, etc. The stored
material texture library may be accessed and applied by an operator when a solid view
is present, so that the surface ofthe displayed part will more closely simulate the actual
texture ofthe sheet metal part.
The wire frame view mode may provide a Windows based display of a wire frame view of the sheet metal part. An example of a wire frame window is shown in Fig. 20.
The key functions for providing 3-D space navigation and 3-D dimensioning in the wire
frame view may be similar to that described above with respect to the solid view. For
example, such functions as rotation, zooming, panning, and standard view selection may
be provided. Automatic dimensioning, multiple view windows and sectional view
options may also be provided in the wire frame view mode. In addition, a joystick and/or
keyboard interface may be provided to permit the user to select and activate the various
viewing functions.
The 2-D flat view mode may display an unfolded, 2-D flat view ofthe part in wire frame representation. An example of a 2-D flat view window is provided in Fig. 21. The 2-D flat view mode may comprise a plurality of viewing functions to permit a user to
change or alter the view in the window. For example, zooming and panning functions
may be provided to permit a user to selectively zoom and pan the 2-D flat wire frame
view. In addition, dimensioning and multiple windows viewing functions may be
provided in a similar manner to that described above with respect to the solid view mode.
A joystick and/or keyboard interface may be provided to permit the user to pan, zoom
and control other viewing functions. Any special forming or shapes that are provided in
the part may be displayed as a form or shape on the outermost boundary of the formed
area with a special forming indicator or description.
An orthographic view window, such as that illustrated in Fig. 22, may also be
provided as part ofthe bend model viewer. The orthographic view mode may display the
top, front, right and isometric views of the part in wire form representation. A hidden
line option may be provided to occlude blocked lines based on the viewing angle. The
hidden line option may be utilized to simplify each view window. Various view
functions may also be provided in the orthographic view mode to permit the user to
selectively manipulate and change the present view in the window. For example,
zooming and panning functions may be provided, as well as dimensioning and multiple
windows viewing functions. As described above, a multiple windows viewing feature
may be provided to permit the user to selectively display a worm view and/or a bird's eye
view of the orthographic views in multiple windows. A joystick and or keyboard
interface may be provided at each of the locations to permit the user to selectively
activate and manipulate each ofthe viewing functions in the orthographic view mode. In addition to rendering each ofthe various view displays noted above, the bend model viewer view class may be implemented with other features. For example, the bend
model viewer may include and maintain a selection set to indicate those items or entities
in the current view that are selected or highlighted by the operator. In accordance with
an aspect ofthe present invention, an operator may be permitted to select faces, bendlines
and other features ofthe rendered part in order to modify the data relating to the selected items or to perform certain operations of those items of the part. For instance, an
operator may be permitted to select a face of the displayed part and change the
dimensional data of the face along its width or length. The operator could also be
permitted to modify the various bend data associated with each bendline, such as the
bend angle or V-width.
The bend model viewer may maintain a list of entities or items (e.g., faces,
bendlines, edges of a face or bendline, etc.) that are selected by the user. The viewer may
update the list so that the current items that are currently selected by the operator are
always maintained in the selection list. Other portions of the software in the invention
may call the view class for the current list of selected entities when performing or
executing different routines (e.g., manual dimensioning, etc.).
In addition, the bend model viewer may also provide a visibility function, which
provides visibility information and coordinate information based on the current rendered
view. As discussed more fully below, the visibility function may provide information
as to whether a particular portion or entity ofthe part is currently visible on the screen
and may also provide coordinate information as to where a screen entity is presently
located. The visibility function of the bend model viewer may be called by a
dimensioning feature ofthe invention in order to determine what portions ofthe part are currently visible on the screen, so that only dimensional information of the portions of
the part that are visible on the screen are displayed to the viewer. A more detailed
discussion of the dimensioning and visibility functions of the invention is provided
below. In addition, an exemplary code for implementing the visibility function of the
bend model viewer is provided in Appendix J attached hereto.
Referring now to Figs. 23-27, an example of a dimensioning feature will be
described in accordance with an aspect of the present invention. As described above,
each of the viewing modes may include a dimensioning function which will
automatically display the dimensions ofthe part based on the current viewing angle. An
automatic dimensioning function may be provided so that the dimension of flanges or bend lines which cannot be seen at the current viewing angle will not be displayed to the
user. When the automatic dimension function or mode is activated, only the viewable
dimensions ofthe part will be displayed based upon the current viewing angle. Further,
in the automatic dimensioning mode, only predetermined dimensions (i.e., those
dimensions which are important to the bending operation) may be displayed based on the
state ofthe current viewing angle. A manual dimension mode may also be provided, to
permit a user to selectively indicate which dimension items are to be displayed. In the
manual dimensioning mode, only those dimension items that have been selected by the
user will be displayed based on the current viewing angle ofthe part. In both dimension
modes, the displayed dimension items may be erased or removed from the window
display when the part is being zoomed or panned.
Fig. 23 illustrates an example of the various dimension items that may be
displayed in an automatic dimension mode. The dimension items that are displayed in the automatic dimension mode consist of those items that are important to the bending
operation (e.g., flange length, bend line length, bend angle, etc.) and not extraneous
dimension items, such as the dimension of a punched hole or opening. The displayed
dimension items may include, for example, the width, depth and height ofthe sheet metal
part, as well as the flange lengths. In addition, the bend line length (L), the bend angle
(A), the inside radius (R) and the bend deduction (D) of each bend line may be displayed
either alone or together in a window or group information box. As noted above, only the
visible dimension items will be displayed based on the current viewing angle. Further,
all dimensions may be erased or removed from the display when the operator is rotating,
zooming or panning to change the viewing angle of the part, and the dimensions may be
redisplayed after each operation has been completed. The size and orientation of the
display information (including any text and reference arrows) may always be sized
relative to the screen size and not to the current zooming ratio or viewing angle.
However, in order to improve the readability of the dimension information, the color,
style, weight and/or font ofthe dimension information may be configurable to permit the
user to alter the same. As a result, an operator or designer may highlight critical
dimensions in a part by selecting a particular color, font size, etc. of the dimension
information. For example, the color, size or font of dimension text, or the color, line
weight, or style of a dimension reference, line or arrow may be highlighted or selectively
altered to indicate critical dimensions within the part. An operator may also be permitted
•to color, fill or style the window information boxes, or to color particular bend lines to
also highlight other critical dimensions within the part.
Various processes and operations may be utilized for implementing the dimensioning feature ofthe present invention. Further, as noted above, the bend model
viewer may be provided with a visibility function that may provide visibility information
to the dimensioning feature of the invention. Theses functions and features may be
implemented by software at, for example, server module 32 and/or each of the station
modules located throughout the factory. Exemplary code is provided in Appendices F-I
to implement the automatic dimensioning feature of the invention. In addition, sample
code for the visibility function of bend model viewer is provided in Appendix J. The
code in these appendices are written in C++ programming language and include
comments to facilitate an understanding of the logic flow ofthe processes and operations
performed therein.
The logic flow of the dimensioning feature of the invention may be generally
categorized into three phases. During the first phase, the bend model geometry and
topology data for the part is accessed from the database 30 and is used to compute all
dimensions of the part, as well as all possible ways that the dimensions can be displayed For each bendline and face of the part, all of the extreme points at which data can be
displayed is computed, and all ways in which the dimension lines and arrows can be
displayed are computed with respect to these points. Certain heuristics may be applied
when determining where the dimension data and other information may be displayed.
For example, as a general rule, it may be determined that all information may only be
displayed on the outside ofthe part. A heuristic such as this may be applied in order to
provide a more meaningful and less crowded display of information to the viewer.
The first phase described above may be executed whenever the dimensioning
feature of the invention is activated by an operator. Altematively, the computations of the first phase may only be done once when the part is initially viewed by the user. In
such a case, the computed data may be stored in memory for subsequent use and
modified when the dimensions or other geometry data ofthe part is modified or changed
by the user. In addition, all of the computations of the first phase may be performed
relative to the geometry of the part and not the view screen, so that the data can be reused
every time regardless ofthe current view or if the view is changed.
A second phase of the automatic dimensioning feature of the invention may be performed whenever the view ofthe part is updated. The main objective of the second
phase is to filter the data developed during the first phase based on what entities of the
part are visible in the changed view. During the second phase, all data that is not visible
in the current view is filtered out so that only the data computed in the first phase that is
presently visible remains. A function call to the bend model viewer may be performed in order to determine what points or portions of the part are presently visible. As noted
above, the bend model viewer may include a visibility function that maintains and
provides information on the visible portions ofthe part based on the present view that is
displayed. Based on the orientation of the part, the bend model viewer may determine
which faces and bendlines ofthe part (as well as what edges or portions of such faces and
bendlines) are visible and which are hidden on the screen.
As noted above, sample code for implementing the visibility function ofthe bend
model viewer is provided in Appendix J. In order to determine what points or portions
of the part are visible, the bend model viewer may determine and maintain the current
view orientation ofthe part and the current zoom aspect or ratio ofthe rendered part. The bend model viewer may use conventional perspective projection techniques (see, e.g., Chapter 12 of MORTENSON) to determine and maintain the current view orientation.
When determining the visibility of any point on the part, the visibility function may first
get the world coordinates (i.e., the coordinates in which the part is represented) of the
point. Then, the screen coordinates (i.e., the pixel location on the screen) corresponding
to the world coordinates are determined for that point based on the current view
orientation and zoom aspect or ratio. Thereafter, based on the screen coordinates it is
determined whether any entity or portion of the part is in front of the point of interest
from the perspective of the screen viewpoint. The hidden nature of a point on the part
may be determined based on whether some other entity or portion of the part is assigned
the same screen point as the point of interest. A function call to a graphics package or
library (such as OpenGl or RenderWare) may be made to determine whether more than
one point ofthe part is assigned to the same screen point. If something is assigned to the
same screen point, then it may be determined if the point ofthe part is behind it based on
the respective Z-buffer depths of the points. The Z-buffer depth is used by graphics
packages, such as OpenGL and RenderWare, to define the distance to each point from
the viewpoint or camera position. The Z-depth may be determined by making a function
call to the graphics package with the points of the part that are in interest.
The above-describedprocessedof the visibility function of the bend model viewer
may be executed whenever there is prompt to the bend model viewer from the auto-
dimensioning feature of the invention. Such processes may, thus, be performed
whenever the current view of the rendered part is modified or altered by the operator. As
discussed above, the bend model viewer may maintain and update the status of the
current view orientation and zoom ratio whenever there is a change made to the orientation of displayed image so as to accurately provide visibility information when
required.
After determining which data is visible, the auto-dimensioning function may
determine (e.g., based on the computations from the first phase) every possible way and
locations that the dimension data and other information may be displayed. A set of
heuristics may be applied to select the best way to display the data from the available
ways that the data may be displayed. For example, a first heuristic may require that the
area of the screen that is closer to the viewpoint of the viewer is preferred. A second
heuristic may define that the data is to be displayed in an area that is closer to the area
where the distance between the possible points defining the dimension is smallest. Other
heuristics may also be applied based on the relative position of other dimension data and
other information to prevent overlapping and crowding on the screen.
After determining the visible portions ofthe part and the best areas to display the information for the visible areas, a third phase ofthe auto-dimensioning function may be
executed to draw the various information on the display screen. For example, based on
the selection of areas to display the information, the dimension information may be
displayed on the screen for each ofthe visible dimensions of the part. Further, based on
which bendlines are visible, bendline information may also be displayed in information
boxes (such as that shown in Fig.23) in areas ofthe screen that do not overlap with other
part information. The part dimensions, including the width, height and depth ofthe part,
may also be displayed on the screen at a predetermined location (e.g., to the lower right
ofthe part) or a location that is closest to that part and that will not overlap or block other information. Figs. 24-27 illustrate the various methods and definitions that may be used when
displaying the dimension items in the dimensioning mode. In particular. Figs. 24A, 24B
and 24C illustrate the manner in which the flange length may be defined for various
different parts. In accordance with an aspect ofthe present invention, the flange length
may be defined as the farthest point on the flange from each bend line. If the farthest
point ofthe flange does not exist on the longest edge ofthe flange which is parallel to the
bend line, then the dimension of the longest flange may be added and displayed in the dimensioning mode. By way of non-limiting examples, Figs. 25A and 25B illustrate
adding an auxiliary flange length for two different types of parts.
When the thickness of a part is displayed, the flange length may be displayed as
an outside to outside dimension. For example, Figs. 26A, 26B and 26C illustrate the manner in which the flange length may be indicated for various parts that are displayed
with thickness. In addition, for parts with an acute angle bend, the flange length may be
indicated in a variety of ways. For example, as shown in Fig. 27A, the flange length may
be displayed based on a tangent dimension definition, in which the flange length is
measured from a tangent line extending from the acute angle bend. Altematively, an
intersection dimension method may be used, such as that shown in Fig. 27B to indicate
the flange length based on a point defined by the intersection of two lines extending from
both sides ofthe acute bend angle. An operator may be permitted to choose between the
tangent dimension or intersection dimension method for displaying the flange length,
and/or a particular dimension method (e.g., the tangent dimension method) may be
provided as a default setting.
In order to facilitate the development of the bending code sequence, a graphical user interface with various display functions may be provided to aid the development of
the bending plan by the operator. Figs. 28-32 illustrate the various processes and
operations that may be performed to develop the bending code sequence through the use
of a graphical user interface, in accordance with another aspect ofthe present invention.
Normally, the initial bend model data and other job information will be developed
by a design programmer through entering the critical geometric and manufacturing data
at server module 32. The resultant bend model file may then be stored in database 30.
Before the sheet metal part may be produced, it will be necessary for a bending operator
to develop a bending sequence for carrying out the required bending operations. The
bending operator must also decide what type of tooling is required and define the tooling
set-up for the bending machinery. This process of developing a bending plan may be
aided and made more efficient by use of a graphical user interface and the various
teachings of the present invention.
In order to develop the bending plan, a bending operator at, for example, bending
station 18, may access and download the bend model and other job information from
database 30. The bend model for the relevant part may be loaded or imported to the
station module on the shop floor at bending station 18 via the communications network
26. This step is generally shown at step S.220 in Fig. 28. Thereafter, at step S.224, the
bending operator may examine the shape and dimensions ofthe part by using the bend
model viewer. At this point, the bend operator may selectively zoom and pan the various
2-D and 3-D views of the part at a display screen located at the bending station. By activating the automatic dimension feature ofthe present invention, the bending operator
may also view the important bending dimensions for the part for carrying out the bending operations.
Once the operator understands the shape and dimensions of the part, the bending
operator may begin to develop the bending plan by selecting and displaying a bend
sequence input window, at step S.228. The bend sequence input window may provide
a graphical user interface to assist a bending operator to create, modify and delete a bend
sequence, and may also enable the operator to specify and enter various manufacturing
parameters (e.g., backgauge location, tooling, NC data, etc.) for each step in the bend
sequence. The bend sequence input window may contain a 2-D flat view image ofthe
part displayed on a portion of the screen (e.g., at the center of the screen or towards the
left hand side ofthe screen). The 2-D flat view image may include the various features
of the unfolded part, including the flanges, holes and openings of the part. As the
bending operator selects and indicates the bendlines and the bending sequence for each
bendline, a solid 2-D or 3-D image of the intermediate part shape at each bending step
may appear and be provided on a portion ofthe screen, such as on the right hand side of
the screen, as shown for example in Fig.29A. The images ofthe intermediate part shapes may be displayed in a sequence corresponding to the entered bend sequence, and may be
simultaneously displayed on the screen with the 2-D fl t view image of the part (such as
in the example of Fig. 29 A) or separately displayed on a different screen display.
Further, as each bendline is selected, the bendline may be highlighted and a bend
sequence number and an insert direction (e.g., represented by an arrow) may be displayed
on or near the bendline, as shown for example in Fig. 29B. The bend sequence number
for each bendline may be set automatically based on the sequence in which it has been selected, or the bend sequence number may be entered manually by an operator after each bendline has been selected. Other manufacturing information relating to the bendline,
such as the bend angle, bendline length and backgauge position, may also be entered
and/or displayed on the screen when each bendline is selected or highlighted, as shown
for example in Fig.29D and 29E. As shown in Figs.29D and 29E. dialog or information
boxes may be displayed on the screen to permit a bending operator to select, enter or
modify the manufacturing information and other parameters related to each bendline.
The dialog or information box may also permit a bending operator to highlight or select
a bendline, and hot function keys or fast switching keys may be displayed in the bend
sequence input window to permit the bending operator to select or enter tooling and view and modify NC data. For example, a bending operator may select a Tool function key
to switch from the bend sequence input window to a tool input display screen or display
screens to enter tooling information. An NC function control key (e.g., NC9 Ex) may
also be provided to permit an operator to view and or modify NC data related to the
bending operations to be performed.
Further, as shown in Figs. 29D and 29E, other function keys and controls may
also be provided related to defining and/or modifying the bendlines and the related
manufacturing information. For example, a Zoom All key may be provided to zoom in
and zoom out ofthe 2-D flat view image; a Backgauge key may be provided to select or
set a position for the backgauge; a Group and Ungroup control key may be displayed to
permit and control the bendlines that are to be bent together; and a control key (e.g., Ama
Bend) may be provided to define special bend operations. Other functions keys may also
be displayed to permit the bending operator to select, modify and/or delete the bend
sequence (e.g., Remove, Clear Fwd, Clear All, OK, Cancel). With the bend sequence input window, the bending operator is able to efficiently view and modify the bend
sequence and the various manufacturing information.
In addition, according to another aspect of the invention, cross-sectional views
of the part and/or a bending simulation of the part may be displayed on the screen for
each bending step in the bend sequence (see, e.g., Fig. 29E). The cross-sectional views
and bend simulations may be selectively displayed on the screen or displayed as each
bending line is selected by a bending operator. The cross-sectional views and bend
simulations may include representations of, for example, the upper and lower bending
tools (e.g., punch and die) and/or a backgauge position or setting, and may be displayed
simultaneously on the screen with the 2-D flat view image of the part or displayed
separately on a different screen display. The backgauge position may be determined
automatically based on the topology ofthe part or may be set or modified by the operator.
If the tooling information for the bendline has not been entered or set by the bending
operator, the cross-sectional view and/or bend simulation may not be displayed on the
screen, or only the representations of the intermediate part shape and a calculated or
defined backgauge position may be displayed. The bend simulations may comprise a
displayedsimulafionof any required flipping of the part, the handling and orientation of
the part, and/or the bending of the part that is performed at each bendline. It is also
possible to simultaneously display, on the display screen with the 2-D flat view image
ofthe part, a cross-sectional view ofthe part before the bending step and a cross-sectional
view of the part after the bending step has been formed (see, for example, Fig. 29E).
These cross-sectional views may be provided on the right hand side of the screen and
may include representations of the upper and lower bending tools and the backgauge for each bending step in the bend sequence. In addition, zoom control or function keys
(Zoo ln and ZoomOut) may also be displayed to permit an operator to control the zoom
ratio or aspect related to the before-bend and after-bend cross-sectional views.
Techniques and processes similar to that disclosed in Japanese Examined Patent
Application No. HEI 7-121418 (published on December 25, 1995 in the names of NIWA
et al.) and Japanese Unexamined Patent Application No. HEI 1-309728 (published on
December 14, 1989 in the names of NAGASAWA et al.), the disclosures of which are
expressly incoφorated herein by reference in their entireties, may be utilized to display
the cross-sectional views and bend simulations ofthe part.
In accordance with an aspect ofthe invention, software or programmed logic may
also be provided to automatically determine the insertion direction for the bend by
calculating the shorter or smaller side ofthe part relative to the selected bendline. Based
on a feature ofthe invention, each bendline may be used to divide the part into two sides.
The insert direction may be determined for each bendline based on the side of the part
that has a smaller or shorter length (e.g., the dimension of the side that is peφendicuiar
to the bendline) or based on the side that has a smaller overall area. If an operator is not
satisfied with the insertion direction that was selected, the operator may flip the insertion
direction, as illustrated in Fig. 29C. The operator may change or flip the insertion
direction by, for example, clicking a select button of the mouse or keypad when the
bendline is highlighted. The insertion direction information may include an arrow and/or
text to indicate the insertion direction of the flange defined by the bendline for bending
the part with a bending apparatus or machinery. The insertion direction information may
be displayed at or near the bendline (see, for example, Figs. 29B and 29C) or at or near the end of related flange (see, for example, Fig.29D). In addition, the insertion direction
information may be displayed when each bendline is selected, or may be selectively
displayed based on input received from a joystick device, mouse device or keyboard
device.
Thus, through the use of a graphical user interface, the bending operator can see
the various intermediate shapes and the forming of the final part based on the selected
bend sequence entered by the operator. Once again, the operator may enter and select
data on the screen through an appropriate input device, such as a joystick interface, a
mouse interface and or a keyboard interface. If the bend operator is not satisfied with the
proposed bend sequence, the bend operator may edit the bend sequence before finalizing
the bending plan, as generally shown at step S.232. The editing of the bend sequence
may be carried out in a variety of ways and methods. In particular, in accordance with
an aspect of the present invention, a drag and drop editing feature may be provided to
facilitate the bending operator in modifying and editing the bend sequence. As shown
in Fig. 30, the operator may edit a selected bend sequence by simply grabbing one ofthe
intermediate part shaped icons or displays provided on the left or right hand side ofthe
screen and dropping it to its desired location in the sequence. Thereafter, based on the
bend operator's modification to the bend sequence, the various intermediate part shapes
illustrated on the screen will be modified to indicate the intermediate bend stages in
accordance with the revised bend sequence. In addition, the bend sequence numbers on
the 2-D flat view image may be revised based on the bend operator's drag and drop
editing ofthe bend sequence.
After the bending sequence has been determined, the operator decides what type of tooling should be used by selecting tools from a stored library of tooling data, as
shown at step S.236. The pertinent tooling information may be displayed to the bending
operator on the shop floor and display menus may be provided to graphically aid the
bending operator in selecting tooling from the library. Once a particular tool has been
selected from the library, the pertinent data relating to the tool may be indicated on the
screen. Fig. 31 illustrates an example ofthe various display menus and data tables that
may be graphically displayed to the bending operator for manual tool selection. In the
example of Fig.31 , successive display menus or screen displays are graphically displayed
in order to aid the bending operator in picking a particular tool from the tool library. The
successively displayed screen displays may be displayed simultaneously on the display device (e.g., in overlapping or cascading fashion), or may be individually displayed with
the screen being cleared before each successive screen display is displayed. Once a
particular tool has been selected, the particular data for that tool may be provided in a
table and displayed to the operator. The data in the tooling library may be predefined and
stored (e.g., in database 30) during an initial set-up procedure ofthe software.
The manual tool selection feature of the present invention may permit a user to
select a tool type and the shape ofthe tool in each type. For example, various tool types
may be selected, including punch, die, die holder, and die rail. Each type may consist of
many shapes, and for each shape there may be many tools with different sizes and
dimensions. To select a tool, a user would first pick one tool type by selecting one icon
from the tool type icons that are displayed, such as that illustrated in Fig. 31. Thereafter,
the user would be provided with a menu of different shapes that are available for the selected tool. After analyzing the tool shapes, the user may select a tool shape by selecting one ofthe shape icons from the displayed shape icons for the selected tool (e.g.,
in Fig. 31 a goose neck shape punch has been selected). Finally, the user may select the
appropriate size and dimension for the tool shape that has been selected. As further
shown in Fig. 31 , a table may be displayed to the user to indicate the different sizes and
dimensions of tools available for the tool shape that was selected. By selecting an item
from the table, the selected tool may be displayed as an icon to replace the generic tool
type icon and to confirm the selection ofthe tool.
At step S.240, the bend operator may then set-up the various tool stages in the
press brake by aid of a graphical interface. Fig. 32 illustrates an exemplary tool set-up
window that may be provided to the bending operator to facilitate definition ofthe tool
set-up to be used in the bending plan. Various punch, die and rail data may be indicated
in the tool set-up window, as shown for example in Fig. 32. The tool and die information
for the sheet metal part may be entered by the operator. A joystick may be provided at
the bending operator's station module to permit the bending operator to indicate the
tooling location and to select the tool and dies from a list of available tools and dies. In
the tool set-up window, the left hand side of the screen may display the profile of the
current tool set-up and the right hand side of the screen may display the location of the
current set-up in the press brake. The current set-up location may be highlighted or
shaded, as shown in Fig. 32. Finally, once the bend operator is satisfied with the bend sequence, the bending
plan information including the tooling and bend sequence information, may be saved
with the bend model in the database 30, as generally shown at step S.242 in Fig. 28.
Actual testing ofthe bend sequence may then be performed with the press brake in order to verify the bend sequence selected by the bend operator. If required, any further
modifications to the tooling definitions or bend sequence may be performed by the
operator or designer at the station module.
Various other features of the invention may be provided to aid the bending
operator in the development of the bending plan. For example, in accordance with
another aspect ofthe present invention, a tooling expert may be provided to automatically
provide to the bending operator suggested tooling and bend sequences based on the part
geometry and other information stored in the bend model. The suggestions from the
tooling expert may be followed or revised by the bending operator after analyzing the
same. In addition, a more complex tooling expert system may be provided to make
tooling suggestions and bend sequence suggestions as to more complex operations based on the geometry ofthe part in the bend file and a profile analysis ofthe tooling to check
for potential collisions and interference. Such expert systems may be used and
implemented with either manual or robot assisted bending machinery. By way of non-
limiting examples, the present invention may be implemented with the features and
teachings disclosed in pending U.S. patent application Serial No. 08/386,369, entitled
"Intelligent System for Generating and Executing a Sheet Metal Bending Plan." in the
names of David A. BOURNE et al., and U.S. patent application Serial No. 08/338,115,
entitled "Method for Planning/Controlling Robot Motion," in the names of David A.
BOURNE et al.. the disclosures of which are expressly incoφorated herein by reference
in their entireties.
As described above, a graphical user interface and various functions may be provided to facilitate the bend operator when developing the bending plan for a sheet metal part. In accordance with another aspect ofthe present invention, additional features
may also be provided to aid in the design and manufacturing of the part. As described
more fully below, various multimedia features may be implemented into the present
invention, such as the storage of audio and visual information, to provide additional
assistance to the bending operator when developing the bending plan or executing a bend
sequence. Further, a collision check feature may be provided that automatically checks
for potential interference and collision between the tools and the parts at each of the
intermediate bending stages. This collision check feature may be provided to replace the
cumbersome and time consuming manual check of the tool profiles and spacing in the
part, which is customarily performed by bending operators when developing a bending
plan. These features and others will now be described with reference to the
accompanying drawings.
In accordance with an aspect ofthe present invention, a method may be provided
for storing audio and video information with the bend model data. Various audio and
video instructions can be recorded at the shop floor to provide special instmctions with
respect to, for example, the handling and bending of the sheet metal part. For this
puφose, a CCD camera or digital camera may be provided at each ofthe station modules
of the various locations 10, 12, 14...20, along with an audio microphone. Other
equipment, such as a video camera with an audio microphone, may be provided at the
station modules to permit the operator or user to record audio and video information. The various recording equipment may be connected to a station module computer at the shop
floor. By way of a non-limiting example, an Intel PROSHARE personal conferencing
CCD camera (available from Intel Coφoration) may be used for recording audio and video information. Other commercially available CCD cameras or digital cameras may
also be utilized to record such information.
The various audio and video information that is stored with the bend model data
may be accessed and retrieved by the user according to various methods and procedures.
For example, menu options may be displayed by the station module to permit the replay
of stored audio and video information. In addition, in accordance with a preferred
embodiment ofthe present invention, an operator may be provided the ability to attach
and associate the stored audio and video information with the various display screens and
views ofthe part by selecting and creating icons that are displayed in the view window.
This feature may be implemented through software and object oriented programming
techniques, whereby an icon object is created and stored within the bend model data
structure. The icon object may contain procedures for retrieving attached audio and
video information from memory based on certain conditions (e.g., the selection of the
icon by the operator by double clicking a mouse or indicating selection by use of a
joystick or other input means). With the icon feature of the present invention, the
operator may associate different audio and video messages or information with different
parts ofthe sheet metal part and to any display. By incoφorating the icon into the part
representation, the icons may be adapted to zoom, rotate and translate with the 2-D and/or
3-D model displays ofthe part as the view is changed on the screen.
Fig.33A illustrates an example of attaching audio and visual information through
the use of icons pasted to a 3-D solid model ofthe part. After the user has recorded the audio and visual information, the operator may paste an icon at any location within the 3-D model window. When the icon is subsequently selected by an operator or user, the stored audio and visual information may be played back and displayed in the window to
provide any special instmctions or messages concerning the part or the area of the part
to which the icon was placed. Other information, such as the simulation or recording of
the bending motion, may be associated with the part by placing icons in proximity to the
various bend lines of the part. The video information concerning the bending motion
may then be played back to the user when the icon is selected.
The operator or user may record both audio and video information, or only record
a simple audio message or a still or motion video signal, that may be selectively played back to the user. The icons that are attached to the window display may graphically
indicate the type of information that is stored (e.g., a microphone icon may be depicted
to indicate that audio information has been stored or a display monitor icon may be
provided to indicate that video information has been stored). Special icons may also be provided to indicate that both audio and visual information are associated with that icon
(e.g., an " A/V" symbol or a video camera icon that includes a microphone). A directory
of icons may be provided and displayed to allow the user to select among the various
icons when attaching audio and/or video information to the screen display or image.
Fig. 33B illustrates another example of a display window that may be
incoφorated with icons for retrieving stored audio and video information. The display
window depicted in Fig. 33B relates to the tool set-up screen image, such as that
describedabove with reference to Fig. 30. In the example of Fig. 33B, audio information
may be stored and retrieved by a microphone icon and separate video information may
be stored and retrieved by pasting a video icon to the display window. The audio and video information may relate to special instmctions or information regarding tool set-up or operation. Further, regardless of the type of window display that is currently active,
the operator may paste as many icons as required to the various areas in the window
display so that different audio and video information may be later retrieved.
In accordance with another aspect of the invention, an image editing window
feature may be provided to facilitate the operator in selecting stored images and applying
them to different screens. The imaging editing window feature may be provided as a
Windows based application that may be accessed at, for example, server module 32 or
any of the station modules provided throughout the manufacturing facility. Fig. 34
illustrates an example of the image editing window that may be implemented in
accordance with the teachings of the present invention. The images displayed in the
image editing window may include images shot by a digital camera or a CAM coder. The images that are displayed on the screen may be selectively chosen by the operator
(e.g., through a mouse or other appropriate data input means) and copied to different
screens so that they may be associated with particular model views of a part. The
operator may then paste the image or an icon to the model window (e.g., a 3-D solid model window of the part, such as that shown above with respect to Fig. 33B). The
images shown in Figs. 33 and 34 are photocopy reproductions of actual screen images;
the actual video images will themselves be clearer, dependent upon the resolution ofthe
camera and screen used. The images can include, e.g., a still or motion video image of
a bending operator discussing or illustratingspecial handling or other instmctions relating
to a bending operation, or may be a video image of a sheet metal bending operation. In
other words, any actual image which may be useful can be taken and later displayed. Thus, the actual images shown in Figs. 33-34 are for illustrative puφoses only. Referrin now to Figs. 35 A and 35B, an example of a collision check function of
the present invention will be provided. In accordance with an aspect of the present
invention, a collision check function may be provided to allow users to check for
potential collisions between the part and punch tool through use of a graphical user
interface. The collision check function may be a Windows based application that may
be accessed at any station module or location within the manufacturing facility. The
automatic collision check function of the present invention may be used by a bending
operator in place of the traditional and cumbersome manual profile check that is
customarily performed when developing the bending plan. Traditionally, when developing a bending plan for a sheet metal part, a bending
operator will first determine the bend sequence for the part. The bend sequence defines
the order and manner in which the sheet metal part is to be bent during production. After
the bend sequence has been determined, the bending operator will select and define the
tooling to be used to carry out each of the bending operations. During this process, the
profile of the tools selected and the intermediate shapes of the part will be analyzed to
ensure that there is no interference or collision(s) between the tools and the part when
carrying out each ofthe bending steps. If a collision or interference is detected, then the
type of tooling selected (or, if necessary, the bend sequence) will have to be modified so
that the bending operations may be carried out without interference or collision between
the tool(s) and the sheet metal part.
When detecting for potential collisions or interference, bending operators have
traditionally relied upon manual methods to analyze the clearance between the profile of
a tool and the bent parts or shapes of the sheet metal component. Typically, a model of the tool profile is constmcted and used by a bending operator. The tool profile model is
manually matched or overlaid with engineering or technical drawings (having the same
scale size as the tool profile model) ofthe various intermediate shapes ofthe sheet metal.
By fitting and matching the tool profile model with the drawings ofthe part, the bending
operator can determine whether there is sufficient space and clearance between the tool
and the part at each ofthe bending steps. This process, however, tends to be cumbersome
and time consuming.
The present invention overcomes the disadvantages of such traditional methods
by providing an automatic collision check function. The collision check function of the
present invention may be implemented through a graphical user interface to permit the
bending operator to check for collisions at each intermediate step within a defined
bending sequence. Figs.35A and 35B illustrate examples ofthe collision check function
implemented through a graphical user interface. When activated, the collision check
function will automatically check for collisions between each intermediate shape ofthe part within the bending sequence and the punch tool or tools defined for that sequence.
The intermediate shapes may be displayed on the screen (see, for example, Figs.35A and
35B) and if a collision is found, the step at which the collision is detected may be
highlighted on the screen. In addition, other display indications, such as text, may be
provided to indicate the number of collisions detected. In the examples of Figs.35 A and
35B, the collision information is provided in the upper right hand area of the display
window. In addition, the type of punch tool or tools for which the collision has been
checked may be displayed or indicated in the upper left hand area ofthe display window.
If a collision is detected for the punch tool selected by the operator, the intermediate shapes or stages at which the collision is detected may be highlighted on the
screen. In this case, an operator may select another punch tool for that particular bending
stage and the collision check function may be reexecuted to determine if a collision will
occur with the second choice for the punch tool. The operator may select a punch tool
for each bend and check for collisions with the collision check function. Drag and drop
editing may be provided to allow the user to change the bend sequence displayed in the
window display by dragging the intermediate bending shapes and dropping it to a desired
position within the proposed bend sequence. The bend sequence may then be modified
based on the drag and drop editing performed by the operator, in a similar manner to that
described above with reference to Fig. 32.
Various processes and operations may be used to implement the collision check
feature ofthe present invention. For example, in order to detect for a potential collision,
the geometry for the selected tool and the geometry for the part at each intermediate
shape may be accessed. The geometrical data relating to the part at each intermediate
step may be generated based on the bend sequence and the part dimensions and topology
data. Each flange ofthe part may be folded in accordance with the bend data (e.g., bend
angle, bendline location, deduction amount, etc.) in order to render the part at each
intermediate stage in the bending sequence. The above described folding process and
deduction compensation features of the invention may then be applied when generating
the geometrical data for the part at each intermediate stage. With the tool and part
geometry, the tool and part may be oriented with respect to one another by placing the
tip ofthe tool at the bendline ofthe part at each ofthe bending stages. A collision may
be detected by analyzing the geometrical data and boundaries ofthe tool and the part and determining whether there are common points or overlapping points in the tool and the
part. When a collision is detected at a particular bending step, that step may be
highlighted on the screen to indicate the detection of a collision to the user.
The tool data that is used to detect for collisions may be actively taken out of a
tool shape library based on the tooling selection(s) made by the user. Recalculation of
a collision at any intermediate bending step may be performed based on a different tool shape or modification of the bending sequence. By providing such features, and
displaying such information through a graphical user interface, such as that described
herein, the potential for collisions may more easily be determined and corrected by the
bending operator.
As described above, a joystick or mouse device may be provided at each ofthe
station modules and locations throughout the manufacturing facility in order to permit
the user to selectively activate and control various viewing functions (e.g., zoom, pan,
rotate, etc.) when viewing the rendered model of the sheet metal part. The joystick
device may be a multi-axisjoystick and include select and control buttons. The joystick
may be implemented through various commercially available joystick devices, including
a Microsoft Side Winder joystick, and may be plugged into a game port ofthe computer
of each ofthe station modules and/or other locations in the facility. The mouse may also
be implemented by any commercially available mouse support software, such as
Windows 95 or Windows NT, and any commercially available mouse device that is
plugged into a game or mouse port ofthe computer at each ofthe facility locations
By way of non-limiting examples, Figs. 36-41 illustrate various aspects of a system for manipulating 3-D geometrical shapes and renderings ofthe part by using a joystick or mouse device. The 3-D navigation system of the invention permits a user to
control various viewing functions, such as rotation, zooming and panning. In accordance
with an aspect ofthe present invention, the system may also use a dynamic rotation axis
that is calculated based on the current zoom view when viewing the 3-D model.
According to this aspect, the center of rotation may be dynamically changed and
calculated based on the current view and zoom ratio or factor so that the zoomed area of
the part will not disappear from the screen when the part is rotated with, for example, a
high zoom ratio or factor.
In accordance with an aspect ofthe present invention, the 3-D manipulation and
navigation system may be provided at the station modules and/or server module of the
facility. The processes and operations ofthe 3-D navigation system may be implemented
through software or programmed logic and by using any one of a wide variety of
programming languages and techniques. For example, the system may be implemented
by using a high level programming language such as C++ and using objected oriented
programmingtechniques. Further, by way of a non-limiting example, VISUAL C++ may be utilized, which is a version ofthe C++ programming language provided by Microsoft
Coφoration for Windows based applications. The viewing functions (e.g., zoom, rotate,
pan, etc.) may be defined and implemented as member functions of the view class of the
bend model viewer ofthe present invention described above (see, e.g., Fig. 18 and the
related disclosure provided above). Information conceming the current zoom factor and
position ofthe part (e.g., the position ofthe part in 3-D space) may also be accessed from
the bend model viewer to calculate the dynamic rotation axis and to provide the desired
viewing functions. Various hardware components and interfaces may also be provided in order to
implement the 3-D navigation system ofthe present invention. For example, the software
used to implement the system may be provided or reside in the computer or personal
computer of the station modules and server module. As discussed above, the computer
or personal computer may include a graphics card and a display screen or terminal, such
as a high resolution monitor, to display 3-D renderings ofthe sheet metal part to the user.
The computer or personal computer may also include a mouse or game port adapter card
to connect and interface with the mouse or joystick device. Commercially available
software may also be provided to inteφret the command signals received by the mouse or game adapter card from the user-operated mouse or joystick device.
Figs. 36A and 36B illustrate examples of rotation functions that may performed
with a multi-axisjoystick 112 to rotate, for example, a simple 3-D box shaped part. As
noted above, a joystick may be provided and connected to a computer or equipment
provided at the station modules and/or server module provided throughout the facility.
As shown in Figs. 36A and 36B, rotation of the part may be achieved by moving the
joystick 112 forwardly or rearwardly, and to the left and the right. The orientation or
direction ofthe rotation axis may be set based on the movement of the joystick 1 12 (or
mouse). For example, moving the joystick 112 forwardly or rearwardly may cause the
part to rotate in the clockwise or counter clockwise direction about a rotation axis defined
along the X-coordinate axis (see, e.g., Fig. 36A). Further, moving the joystick 112,
however, to the left or right may cause the part to rotate in the clockwise or counter
clockwise direction about a rotation axis defined along the Y-coordinate axis (see, e.g., Fig. 36B). When the zoom ratio or factor ofthe current view is low and the entire rendering
ofthe part is provided on the screen, the rotation axis may be defined as passing through
the geometric center or centroid ofthe part. As described above, the zoom factor and the
visibility of the part on the screen may be determined based on the visibility function
provided by the bend model viewer ofthe present invention. When it is determined that
the entire part is displayed in the screen (such as that in Figs. 36A and 36B), then
coordinate geometry techniques may be used to define and set the rotation axis to the
geometric center ofthe part. Rotation ofthe part may then be performed based on the
user-defined movement ofthe joystick device and through the rotate member, viewing
function of the bend model viewer of the present invention.
If, however, only part ofthe object is displayed on the screen and it is determined
that portions of the part are not visible (e.g., a high zoom factor or ratio has been
selected), the rotation axis should not be maintained at the geometric center or centroid
ofthe part, since to do so may cause the zoomed portion ofthe part to disappear from the
screen during rotation. Instead, according to the invention, when the zoom ratio is
increased, the rotation axis is dynamically recalculated such that the rotation axis passes
through the coordinate ofthe closest point to the viewpoint (or camera view) at the center
of the screen. By dynamically recalculating the rotation axis based on changes in the
zoom factor, the part may rotated about an axis that does not cause the visible portion of
the part to go out of view during rotation.
In order to perform zooming and panning of the 3-D model, additional control
buttons may be provided on a keypad that is provided separately or with the joystick or mouse device. For example, by pressing a zoom button 1 14, and moving the joystick 112 forwardly or rearwardly, the part may be zoomed in or out based on a predetermined rate,
as shown in Fig. 37. As discussed above, the rotation axis may be recalculated within
each zoom window to permit the user to view the zoomed portion of the part when
rotation is performed. In addition, panning of the 3-D shape may be controlled by the
user by pressing or activating a pan button 1 16 and moving the joystick 112, as shown
in Fig.38. As with the zoom button 1 14, the pan button 1 16 may be provided on a digital
input pad that is provided separately or with the joystick or mouse device at each ofthe
various locations ofthe facility.
In accordance with an exemplary embodiment of the invention, the various
processes and operations that may be provided to implement the 3-D navigation and
manipulation system will be described below with reference to Figs. 39-41. As indicated
above, the necessary processes and operations of the 3-D navigation system may be
implemented through a combination of software or programmed logic, and hardware
components and interfaces. Input signals from a user-controlled device, such as a
joystick or mouse device, may be inteφreted to determine the amount of movement and
reorientation of the rendered part that is desired. In accordance with the invention, the
rotation axis of the rendered part may be calculated dynamically, based on the current
view and zoom factor, in order to prevent the zoomed area ofthe part from disappearing
from the screen during rotation.
When updating the current view ofthe rendered part, input signals are received
from the user based on the manipulation ofthe joystick or mouse device, as generally
indicated at step S.301 in Fig. 39. Movement of the joystick or mouse device by the user in a particular direction, and/or in combination with the activation of special control buttons, may cause certain viewing functions (e.g., rotate, zoom, pan, etc.) and movement
of the rendered part in predetermined directions (e.g., clockwise or counterclockwise;
zoom-in or zoom-out; left or right; etc.) to be effectuated, as described for examples in
Figs.36-38. The received signals, whether they are from a joystick or mouse device, may
be mapped to cursor movement to define the amount of movement on the screen that is
desired by the user. If the user is not within one ofthe viewing function modes (e.g., the
user is selecting information on the screen or reviewing information in a dialog box or
window), then mapping of the received signals may not be required.
As will be appreciated by those skilled in the art, the signals that are received
from conventional joystick or mouse devices are based on different coordinate or
reference systems than that ofthe screen space, and must be translated in order to provide
meaningful information regarding cursor movement on the screen. Therefore, after
receiving the input signals from the user, the received signals may be mapped to cursor
movement, as indicated at step S.303, before calculating the rotation axis and updating
the current view of the rendered part.
Different methods and processes may be used to translate and map the input
signals from the user-controlled device to cursor movements in screen space.
Traditionally, movements of a mouse device have been translated and mapped to cursor
movements by commercially available software. For example, Windows 95 and
Windows NT include software routines for translating mouse movements to cursor
movements. As such, movements of a mouse device may be mapped to cursor movement
by using such commercially available software. If, however, the user is provided with
a joystick interface, then the joystick movements should also be translated and mapped to cursor movements in order to provide useful information. Various methods and
techniques may be used to map the joystick movements within the joystick virtual space
to cursor movements within the screen space. For example, the joystick movement
signals may be first processed and translated to mouse movements before they are finally
mapped to cursor movements. Altematively, the joystick signals may be directly mapped
to cursor movements as a function ofthe ratio ofthe screen space size to the size ofthe
joystick virtual space.
Fig. 40 illustrates an example of mapping joystick movements to cursor
movements in screen space, in accordance with an aspect ofthe present invention. As
indicated above, a joystick device may include its own virtual coordinate system or space 218. The joystick virtual space 218 includes an origin J 1 that corresponds to the position
at which the joystick is in a center or neutral position (i.e., a position at which the
joystick is not moved). When the joystick is moved to a new position (e.g., a current
position J2 as shown in Fig. 40), the joystick device generates signals to indicate the new
or current position within the virtual space of the joystick. Since the joystick virtual
space 218 is often larger (in terms of pixels) than the screen space 212, the virtual
coordinates and movements of the joystick must be translated to screen coordinates in
order to determine the desired cursor movements and, thus, movement ofthe part on the
screen.
Various methods and processes may be utilized to map and translate the virtual
coordinate movements of the joystick to screen coordinate movements. For example,
joystick movements may be mapped to screen cursor movements based on the ratio of
the screen space size to the joystick virtual space size. More particularly, when it is determined that a viewing function mode (e.g., zoom, rotate, pan, etc.) is active and the
joystick device has been manipulated by the user, the actual movement ofthe cursor from
a previous point Cl to current point C2 may be determined by the following equation:
current_point = previous_point + (scale factor x V); wherein, "current_point" is the
current point C2 of the cursor; "previous_point" is the previous point Cl ofthe cursor;
"scale_factor" is the ratio of the screen size to the joystick virtual space size (both in
pixels); and "V" is a vector representing the movement and direction of the joystick from
the joystick origin JI to the joystick current position J2. Thus, in order to map joystick
movements to cursor movements, a vector "V" indicating the direction and movement
of the joystick from the origin J 1 to the current position J2 may first be calculated based
on the signals received from the joystick device when it is manipulated by a user. After the vector "V" has been calculated, the joystick movement may be mapped to cursor
movement by using the vector "V" amount and the "scale f actor" amount in the equation
describedabove; that is, the new or current position C2 ofthe cursor may be calculated
by multiplying the vector "V" by the ratio of the screen size to the joystick space size
(i.e., the "scale factor"), and then adding the result of this computation to the previous
cursor position Cl .
Depending on the scale factor, it may be necessary to increase or decrease the rate
of scaling or movement by a predetermined or user selected adjustment factor. In such
a case, and depending on the preference ofthe user, the scale factor may be multiplied
by the adjustment factor when calculating the current point of the cursor in order to
increase or decrease the rate of scaling. For example, if the ratio of the screen size to the
joystick space size provides a scale factor of 1/64, then it may be preferable to increase the rate of scaling in order to provide a more satisfactory relationship between
movements of the joy stick and the rate of movement ofthe rendered part on the screen.
By way of a non-limiting example, with a scale factor of 1/64, an adjustment factor of 3
may be used when zooming or rotating the rendered part. Further, for a scale factor of
1/64, an adjustment factor of 6 may be used when panning of the rendered part is
performed. Of course, the rate of scaling may be modified based on the particular needs
ofthe user, and the adjustment factor may be predetermined or the user may be given the
option to adjust or select the adjustment factor to modify the rate of scaling. Further, as
indicated in the example discussed above, the adjustment factor may be set to the same
amount for each of the viewing functions or may be individually set to the same or different amounts for each ofthe viewing functions provided.
After the received signals have been appropriately mapped and translated, the
rotation axis ofthe part may be dynamically calculated, as generally shown at step S.305
in Fig. 39. Depending on the current view of the part, the rotation axis may be defined
to pass through the center ofthe part or to pass through another point so that the zoomed
area of the part will not disappear from the screen when the part is rotated with, for
example, a high zoom ratio or factor. Various methods and processes may be utilized to
dynamically recalculate the rotation axis ofthe part based on the current zoom view. In
accordance with another aspect ofthe invention, Fig. 41 illustrates an exemplary logic
flow and sequence of processes and steps that may be performed to calculate the rotation
axis whenever the view ofthe part has been modified by the user.
As shown in Fig. 41, the current zoom factor or ratio and the part position and
current view may be determined at steps S.311 and S.313. The zoom factor and orientation of the rendered part selected by the user will cause the entire part to be visible
on the screen (i.e., a full view) or cause only a portion ofthe part to be made visible on
the screen (i.e., a partial view). Thus, the current zoom factor and part orientation should
be determined in order to properly set the rotation axis of the rendered part. Various
methods and processes may be used in order to determine the current view ofthe part.
As described above, a visibility function may be provided with the bend model viewer
ofthe present invention to maintain and update the status ofthe current view orientation
and zoom ratio whenever there is a change made to the displayed image. A function call
may be made to the bend model viewer to determine what points or portions of the part
are presently visible. Whether all of the part is displayed on the screen may be
determined by comparing the view volume with the part's boundary base size.
If it is determined at step S.315 that a full view of the part is currently visible on
the screen, then the rotation axis may be set to pass through the center of the part at step
S.317. Setting the rotation axis to the center of the part when there is a full view is
possible, since the entire rendered part will be visible on the screen when it is rotated by
the user. With the entire part visible on the screen, the rotation axis may be defined so
as to pass through the geometric center or centroid of the part. Conventional coordinate
geometry techniques may be used to define and set the rotation axis to the geometric
center of the part. In addition, the direction of the rotation axis may be defined as a
vector that is peφendicuiar to the vector from the previous cursor position to the current
cursor position.
If it is determined at step S.315 that only a partial view of the part is currently
visible on the screen, then logic flow may continue to steps S.319-S.325 in order to calculate the rotation axis so that portions ofthe rendered part will not disappear from the
screen when the zoomed part is rotated by the user. As described above, when a high
zoom factor is selected by the user and only portions of the part are displayed on the
screen, the rotation axis should not be set to pass through the geometric center ofthe part,
since to do so may cause the zoomed portion(s) ofthe displayed part to disappear from
the screen during rotation. In order to prevent the displayed portion of the part from
being occluded or disappearing from the screen, the rotation axis should be set so as to
pass through the coordinate of the closest point to the viewpoint (i.e., camera) at the
center of the screen. In such a case, the direction ofthe rotation axis may be defined as a vector that is peφendicularto the vector from the previous cursor position to the current
cursor position.
Thus, at step S.319, the center ofthe screen is located and the object or portion
ofthe part at the center ofthe screen that is closest to the camera is selected. That is, the
portion of the rendered part that is located at the center of the screen and that is closest
to the camera or user viewpoint ofthe screen is picked.
If it is determined at step S.321 that there is an object at the camera (e.g., that there is a
solid portion ofthe part that is located at the center ofthe screen and that is closest to the
camera), then at step S.325 the rotation axis may set to pass through the picked point.
As discussed above, the direction ofthe rotation axis may be defined as a vector that is
peφendicuiar to the vector from the previous cursor position to the current cursor
position.
If it is determined at step S.321 that there is not an object at the camera (e.g., that
the part includes a hole or opening that is located at the center of the screen and that is closest to the camera), then logic flow may continue to step S.323. At step S.323, the
rotation axis may altematively be define to pass through the center ofthe screen (e.g., the
X and Y coordinate of the physical center of the screen) and at the Z-coordinate (i.e.,
depth) equal to the geometric center ofthe part. Thus, the rotation axis may be set to pass
through the X, Y, and Z coordinates discussed above, with the direction ofthe rotation
axis being defined as the vector that is peφendicuiar to the vector from the previous
cursor position to the current cursor position.
Referring back to Fig. 39, after the dynamic rotation axis has been calculated, the
selected viewing function (e.g., zoom, rotate, pan, etc.) may be called at step S.307. As
discussed above, the various viewing functions of the 3-D manipulation system may be
defined and implemented as member functions of the view class of the bend model
viewer (see, e.g., Fig. 18 and the related disclosure provided above). In such a case,
based on the viewing function selected by the user, a function call may be made to the
bend model viewer to update the current view ofthe rendered part, at step S.309. The
current view and orientation of the part may be updated based on the viewing function
selected by the user and the mapped cursor movements received from the user-controlled
input device (e.g., the mouse or joystick device). A graphics package, such as OpenGL
or RenderWare, may be provided to facilitate the update ofthe current view provided to
the user.
The logic flow and processes performed in the exemplary flowcharts of Figs. 39
and 41 may be implemented by software and by using a wide variety of programming
languages and techniques. For example, object oriented programming techniques and
C++ may be used to implement the noted processes and operations. An exemplary code for implementing the 3-D manipulation system ofthe present invention is provided in
Appendix L. The exemplary source code was written in C++ programming language and
includes the various processes and operations for calculating the dynamic rotation axis.
Comments are provided in the code of Appendix L to facilitate the analysis ofthe logic
and algorithms used therein.
Although the 3-D manipulation system described above has been described with
respect to the use of a joystick device and control buttons, the system may also be
implementedby any other particular type of input means, including a mouse or keyboard.
Further, in the above-described embodiments of Figs. 37-38, boundaries may be defined
to limit zooming or panning ofthe object in or out ofthe screen into infinity, since such continuous zooming or panning may cause the system to fail or crash.
In addition, various other features may be implemented in connection with the
joystick interface. For example, movement in any ofthe viewing functions may not be
effectuated unless the joystick is moved beyond a predetermined range or distance from
the joystick center position. Requiring such a threshold of movement of the joystick
before movement ofthe part is permitted prevents accidental movements ofthe rendered
part based on inadvertent handling or pushing of the joystick from the center position.
Other features may also be provided to improve the joystick interface and system
interaction with the user. For instance, continuous or incremental (e.g., step-wise)
movement in any one of the viewing functions (e.g., zoom, rotate, pan, etc.) may be
provided based on the single operation of the joystick by the user. Selection of the
continuous or incremental movements may also be provided based on the amount or
duration of movement of the joystick in any single direction. If desired, the rate of scaling or movement ofthe rendered part may also be increased based on the degree or
duration of movement of the joystick in any direction. Modification of the speed
adjustment factor described above may also be implemented by permitting the user to
manual insert the correction to the adjustment factor to increase or decrease the rate of
scaling.
Various other features and embodiments may also be implemented in the present
invention in order to aid in the design and manufacturing of components at the factory.
For example, a bar code system may be implemented to keep track of and access
information concerning each customer's order. A bar code with a predetermined
reference or job number may be assigned to each part ordered by a customer. This bar
code may be used for accessing and retrieving job information from database 30. A bar
code reader or scanner, such as a Barcode Anything SCAN CCD sensor from Zebra
Technologies VTI, Inc., Sandy, Utah, may be provided at each ofthe locations to permit
users to scan the bar code for a particular job in to the server module or station module
and to access and retrieve critical design and manufacturing information associated with
that part that is stored in database 30. The bar code reader may be plugged into the
computer of each of the station modules and/or the server module. The bar codes may
be formatted in accordance with any conventional bar code formats, such as UPC-A,
Codabar, Code 39, EAN/JAN-8 or Plessey, and the resultant bar code number may be
translated in accordance with a lookup table to find the corresponding job reference
number and/or file name in order to retrieve the job information from the database.
Altematively, the job number may be typed in or selected from a displayed directory at any ofthe stations located throughout the factory to instantaneously retrieve and display the job information at the user's location. The ability to instantaneously retrieve such
information is aided by the use of communications network 26 and the storage of the
design and information at a centrally located database, such as database 30.
In accordance with yet another aspect ofthe present invention, an apparatus and
method for scheduling and assigning jobs may be provided in the proposed system.
Conventionally, the scheduling and assignment of jobs throughout a manufacturing
facility is performed by a shop or factory foreman who determines the current set-up and
availability of machinery, as well as the status of current jobs. After gathering and
analyzing this information, the shop or factory foreman may develop a schedule and
distribute the assignments for the jobs (e.g., in the form of a job schedule sheet that is
distributed to the factory floor) that are to be performed at the various locations in the
factory. The scheduling and assignment of jobs is provided to ensure that each
customer's job is completed in a timely fashion and by the specified delivery date. The
conventional process of scheduling and assigning jobs is, however, often arduous and
usually performed manually by the factory foreman.
In accordance with an aspect ofthe invention, a job assignment and scheduling
system may be provided to assist a shop or factory foreman in establishing job schedules
for the factory. The system may take advantage of communications network 26 and the
bend model information that is stored in database 30 to automatically gather the
necessary information so that the shop foreman may more easily develop a job schedule.
The system may be implemented through software or programmed logic at the server
module or station modules located throughout the factory. By entering the various jobs
that need to be scheduled, the system software may analyze the design and part information and determine which machines are best suited for doing particular jobs. For
this puφose, the current status and set-up ofthe machinery in the factory may be defined
and stored in database 30 and accessed by the job scheduler software. Based on various
criteria, the software may suggest to the foreman, in the form of a display, which
machines are available to perform a particular job and which machines cannot perform
other jobs. In this regard, a table may be displayed that ranks the availability of machines
for particular jobs and that provides a proposed job schedule that may be implemented
or modified by the shop foreman.
The criteria that may be used to set and recommend job schedules may include
a wide variety of criteria including the current set-up of each machine in the factory, the
types of bends and tooling required for each job and the other types of jobs that need to
be performed within the same time frame or period. Information from the bend model
file for each part may also be utilized, such as the bend angle, the flange length, and type
of bending, in order to determine which machines can perform a particular job. A table
stored at, for example, database 30, may include critical information as to the current set¬
up and capabilities of each ofthe punching and bending machines on the shop floor.
Based on the proposed job schedule, the foreman may assign jobs to various
locations throughout the factory in order to optimize production and output capacity of the factory. The final job schedule or assignment may be entered electronically and
routed to each of the machines through communications network 26. A pilot lamp, such
as an LED, may be provided at each of the bending or machinery work stations to
indicate and confirm that a job has been assigned or transferred to that station. The job
assignment and schedule may be stored in a file ofthe server module that can be accessed instantaneously from any location within the factory.
In addition to the above features, other miscellaneous features may be
implemented in accordance with the teachings of the present invention. For example,
menu screens may be provided and displayed at the various station modules and locations
to facilitate the user in selecting the various display and function modes ofthe present
invention. For example, a main menu screen such as that shown in Fig. 42 may be
provided to a user when the station module is initialized. The main menu window
display may include icon images of each of the available window displays and viewing
modes provided by the station module. The main menu screen may pop-up anytime a
menu button (e.g., FI key) is selected. The user may select a window by moving a
highlighted block to the desired window icon and selecting the same. Such operations
may be performed through the use of a keyboard, mouse or joystick.
Other window screens may also be provided and displayed to the user to facilitate
the entry and display ofthe job information. For example, a part information window
may be displayed to permit a user to enter or modify the part information. An example
of a part information window display is provided in Fig. 43. The part information
window may include all of the pertinent part information (e.g., part number, material
type, dimensions, etc.) and may include a 2-D flat drawing and isometric view of the
sheet metal part. A bendline information window, such as that illustrated in Fig. 44, may
also be provided to allow a user to view the various bendline information, including the
bend sequence and deduction amount for each bendline. The bendline information
window may permit the user to enter or modify the bendline information for each bend,
and may include both a 2-D flat drawing and isometric view ofthe sheet metal part. Additional window display may also be provided to facilitate a bending operator's
analysis ofthe bending sequence. For example, a bend sequence window display and a
bend simulation window display may be provided to indicate the various bending stages
of the part and to simulate the part orientation during bending operations. A bend
sequence window, such as that shown in Fig. 45, may be selected from the main menu
screen and displayed to the user to indicate the intermediate shapes ofthe part (in static form) at each stage ofthe bending sequence. A bend simulation window (see, e.g., Fig.
46) may also be selected by the user and provide both static information ofthe bending
stages (in the form of part icons provided on the righthand side of the screen) and active
simulation (in the center ofthe display) ofthe orientation and bending performed at each stage in the bend sequence. By intermittently selecting the part icons on the screen, the
user may view an active simulation ofthe orientation of the part during bending at the
stage represented by the selected part icon. The part may be flipped, translated and
bent/rotated about the bendlines in order to actively simulate each bend sequence.
Each ofthe above-described window displays of Figs. 43-46 may be selected and
displayed to a user from the main menu window display of Fig. 42. In addition, a user
at any of the station modules may select the appropriate window icons in the main menu
window display to have the 2-D and/or 3-D representations of the part displayed in
accordance with the viewing modes (e.g., 2-D flat, wire-frame, solid, orthographic) of the
invention, as described in greater detail above with reference to Figs. 19-22. Various
menu windows may also be provided, for example, at the station modules to facilitate the operation of the features and functions of the present invention. Fig. 47 illustrates
exemplary menus that may be displayed for the 2-D to 3-D operations. In addition, Fig. 48 illustrates an exemplary menu structure for the 2-D cleanup operation ofthe invention
The present invention, however, is not limited to these menu arrangement, and other
menu screens and/or tool icon bars may be provided to facilitate a user's interaction with
the system.
Other features may also be implemented in the present invention. For example,
higher levels of automation may be provided to facilitate the development of the bending
plan. For example, bending and tooling expert systems may be provided to develop and
propose tooling set-up and bending sequences based on the part geometry and shape for
each job, such as that disclosed in pending, U.S. patent application Serial Nos.
08/386,369 and 08/338,1 15.
While the invention has been described with reference to several exemplary embodiments, it is understood that the words which have been used herein are words of
description and illustration, rather than words of limitations. Changes may be made
without departing from the scope and spirit of the invention and its various aspects.
Although the invention has been described herein with reference to particular means,
materials and embodiments, the invention is not intended to be limited to the particulars
disclosed herein; rather, the invention extends to all functionally equivalent structures,
methods and uses. APPENDIX A
///////////////////////////////////////////////////////////////////
// //
// Example of feature entity extraction from BendModel parts //
// //
// //
// Copyright 1996 AmadaSoft America, Inc. //
// //
/////////////////////////////////////////////////////////////////// int SPS_cal_part_matrix ( BM_PART *part, FENT **inp_sp, char *pname, int *inp_parran , int *inp_part_numface, int *inp_part_numbend, int *inp_part_maxface )
{
// local variables int parrank, part_numface, part_numbend, part_maxface ; int **imatrix = NULL ; int *nbl_face = NULL ;
BENDFACE *facelist = NULL ;
BENDLINE *bendlinelist = NULL ;
ARTIFICIAL_FACE *bendfacelist = NULL ;
int num_error = 0 ; // counter for the number of errors in the part int face_l, face_2, bend_l, bend_0, i ; long num_of_faces, num_of_bendlines, entity_id;
BM_FACE *face;
BM_BENDLINE *bendline;
BM_2D_BODY *t o_d_body;
BM_3D_BODY *three_d_body;
BM_BEND_OP *bend_op;
BM_TOPOLOGY_RECORD *topology_record;
// get name and number of faces and bendlines of the part part->get_name{ pna e ) ; double thickness = part->get_metal_thickness () ; num_of_faces = part->get_number_of_faces() ; num_of_bendlines = part->get_number_of_bendlines () ; APPENDIX A
if (num_of_faces == 0 | | num_of_bendlines == 0) return ( -1 ) ;
// create local working array facelist = new BENDFACE [num_of_faces] ; bendlinelist = new BENDLINE [num of bendlines] ;
// count number of faces defined. double maxfacearea = -1.0 ; part_maxface = 0 ,- part_numface = 0 ; face = part->get_face_list () ; for ( i = 0 ; face && i < num_of_faces ; i++, face = (BM_FACE *) (face->next () ) ) { // Count the defined faces.
// initialize the struc facelist [i faceid = 0 ; facelist [i facept = NULL ; facelist [i .twodpt = NULL ; facelist [i , hreedpt = NULL ; facelist [i ,topologyrecpt = NULL facelist [i ,numadjbody = 0 facelist [i .numadjbend = 0 facelist [i ,numadjhole = 0 facelist [i .numadjface = 0 facelist [i .face area = 0.
if (face == NULL) break ; two_d_body = face->get_3D_version() ; if (two_d_body == NULL) continue ;
// It is considered as a valid face, when its BM_2D_BODY exists. part_numface++ ; facelist [i] . faceid = part_numface ; facelist [i] .facept = face ; facelis ti] .twodpt = two_d_body ; facelist [i] .face_area = area_of_a_2D_body(two_d_body) ; if (maxfacearea < facelist [i] .face_area) { maxfacearea = facelis [i] .face_area ; part maxface = facelis fi] .faceid ; APPENDIX A
} three_d_body = two_d_body->get_3D_body() ; facelist [i] .threedpt = three_d_body ;
if (three_d_body == NULL) continue ; entity_id = three_d_body->get__name () ; facelist [i] .org_entity = entity_id ; topology_record = three_d_body->get_adj_list () ; facelist [i] .topologyrecpt = topology_record ;
if (topology_record == NULL) continue ; facelist [i] .nu adjbody = (int) topology_record->get_number_of_adjacent_bodies () ; facelist [i] .numadjface = (int) topology_record->get_number_of_adjacent_faces () ; facelist [i] .numadjhole = (int) topology_record->get_number_of_adjacent_holes () ; facelist [i] .numadjbend = (int) topology_record->get_number_of_adjacent_bendlines () ; } if (num_error > 0) { clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ; return ( num_error ) ;
} if (part_numface == 1) {
// this is a trivial case, where the part only has one flat face.
*inp_part_numface = part_numface ;
*inp_parrank = part_numface ;
*inp_part_numbend = 0 ;
*inp_part_maxface = 1 ;
*inp_sp = new FENT [2] ;
*inp_sp[2] = NullFent ; clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ; return ( 0 ) ;
} APPENDIX A
// varify all the valid face, the current requirements are: // 1) A face cannot be adjacent to another face. // 2) A face without an adjacent bendline is not allowed. // (Note: The single faced part has been processed.) // Also, creat a pointer array that links assigned part__face_id
// to the netry in the facelist. int *fid_pt = new int [part_numface] ; for ( i = 0 ; i < num_of_faces ; i++) { if (facelist [i] .faceid) { fid_pt [facelist [i] .faceid] = i ; if (facelist [i] .numadjface | | facelist [i] .numadjbend < 1) num_error++ ;
}
} if (fid_pt) delete [] fid_pt ; if (num_error > 0) { clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ,- return ( num__error ) ;
}
// count the number of bendlines that is defined. part_numbend = 0 ; bendline = part->get_bendline_list () ; for ( i = 0 ; bendline && i < num_of_bendlines ; i++, bendline = (BM_BENDLINE *) (bendline->next ()) )
{
// initialize the struct bendlinelist [i] .bendlineid = 0 ; bendlinelist [i] .bendlinept = NULL ; / / BM_BENDLINE pointer bendlinelist ti] .bendoppt = NULL ; / / BM_BEND_0P pointer bendlinelist ti] .twodpt = NULL ; / / BM_2D_BODY pointer bendlinelist [i] .threedpt = NULL ; / / BM_3D_B0DY pointer bendlinelist [i] .topologyrecpt = NULL ; / / APPENDIX A
BM_TOPOLOGY_RECORD pointer bendlinelist [i] .numadjbody = 0 bendlinelist [i] .numadjbend = 0 bendlinelist [i] .numadjhole = 0 bendlinelist [i] .numadjface = 0
if (bendline == NULL) break ; two_d_body = bendline->get_3D_version() ; if (two_d_body == NULL) continue ;
// It is considered as a valid bendline, when its BM_2D_BODY exists. part_numbend++ ; bendlinelist [i] .bendlineid = part_numbend ; bendlinelist [i] .bendlinept = bendline ; // BM_BENDLINE pointer bendlinelist ti] . twodpt = two_d_body // BM 2D BODY pointer bend__op = bendline->get_bend_op() ; bendlinelist ti] .bendoppt = bend_op ; // BM_BEND_0P pointer if (bend_op == NULL) num_error++ // Note: Bend operation must be defined for each // bendline, otherwise it is an error. three_d_body = two_d_body->get_3D_body () ; bendlinelist [i] .threedpt = three_d_body ; // BM_3D_B0DY pointer
if (three_d_body == NULL) continue ; entity_id = three_d_body->get_name () ; facelist [i] .org_entity = entity_id ; topology_record = three_d_body->get_adj_list ( ) ; bendlinelist [i] . topologyrecpt = topology_record ;
if (topology_record == NULL) continue ; bendlinelist [i] . numadj body = ( int ) topology_record- >get_number_of _ad j acent_bodies ( ) ; bendline list [i ] . nuraadj ace = ( int ) topology_record- >get_number_of_adjacent_f aces ( ) ; APPENDIX A
bendlinelist [i] .numadjhole = (int) topology_record- >get_number_of _adj acent_holes ( ) ; bendlinelist [i] .numadjbend = (int) topology_record->get_number__of_adjacent_bendlines ( ) ;
} if (num_error > 0) { clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ; return ( num_error ) ;
}
// varify all the valid bendlines, the current requirements are:
// 1) The total number of bendlines should not be less than
// the total number of faces minus 1.
// 2) A bendline without an adjacent face or bendline is not allowed.
// 3) A bendline with more than two adjacent faces and bendlines is not allowed.
// 4) The adjacent face or bendline of a bendline must be a valid face or
// bendline that is defined in the facelist or bendlinelist.
// 5) Two adjacent faces, facel and face2, will be defined for each bendline
// a) If the bendline has an adjacent faces, then the face's faceid is used
// as facel or face2.
// b) If the bendline has an adjacent bendline, then a bendline_only_face
// will be created inbetween these two bendlines. The faceid of the
// bendline_only_face will be used as facel or face2.
// c) If the bendline has only one adjacent face or adjacent bendline, then
// a bendline_only_face will be created for this bendline. The faceid of
// the bendline_only_face is face2.
// maxnewfaces is the maximum number of bendline_only_face APPENDIX A
need to be created
// without encounter error in the part. if (part_numbend > part_numface-l) num_error++ ; // condition 1 if (num_error > 0) { clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ; return ( num_error ) ;
} int maxnewfaces = part_numbend + 1 - part_numface ; if (maxnewfaces > 0) ( bendfacelist = new ARTIFICIAL_FACE [maxnewfaces] ; bendfacelist [0] . faceid = -part_numface ;
} for ( i = 0 ; i < num_of_bendlines ; i++) { if (bendlinelist [i] .bendlineid) { bend_0 = bendlinelist [i] .bendlineid ; int numadj = bendlinelist fi] .numadjface + bendlinelist [i] .numadjbend ; if (numadj < 1 | | numadj > 2) num_error++ ; // condition 2 & 3 else { if (bendlinelist [i] .numadjface > 0) { / / condition 4 - first face t h r e e _ d _ b o d y bendlinelist fi] .topologyrecpt->get_first_face () ; face_l = find_face_id( three_d_body, facelist, num_of_faces ) ; if (face_l <= 0) num_error++ ; else bendlinelist [i] .facel = face_l ;
} if (bendlinelist [i] .numadjface == 2) { / / condition 4 - second face t h r e e _ d _ b o d y bendlinelist [i] . topologyrecpt->get_next_f ace () ; face_l = f ind_f ace_id ( three_d_body, facelist, num_of_faces ) ; if (face 1 <= 0) num error ++ ; APPENDIX A
else bendlinelist [i] .face2 = face_l ;
} if (bendlinelist [i] .numadjbend > 0) { // condition 4 - first bendline t h r e e _ d _ b o d y bendlinelist [i] . topologyrecpt->get_f irst_bendline ( ) ; bend_l = find_bendline_id( three_d_body, bendlinelist, num_of_bendlines ) ; if (bend_l <= 0) num_error++ ; else { face_l = define_bendline_only_face ( bend_l, bend_0, bendfacelist, maxnewfaces ) ; if (face_l <= 0) num_error++ ; else { if (bendlinelist [i] .numadjface
> 0) bendlinelist ti] .face2 = face_l else bendlinelist[i] .facel face 1
}
} if (bendlinelist [i] .numadjbend == 2) { // condition 4 - second bendline t h r e e _ d _ b o d y = bendlinelist [i] . topologyrecpt->get_next_bendline () ; bend_l = find_bendline_id( three_d_body, bendlinelist, num_of_bendlines ) ; if (bend_l <= 0) num_error++ ; else { face_l = define_bendline_only_face ( bend_l, bend_0,
bendfacelist, maxnewfaces ) ; if (face_l <= 0) num_error++ ; else bendlinelist fi] .face2 = face 1 APPENDIX A
} } if (numadj == 1) { face_l = define_bendline_only_face ( bend 0, 0,
bendfacelist, maxnewfaces ) ; if (face_l <= 0) num_error++ ; else bendlinelist [i] . face2 = face_l ;
}
}
}
} if (num_error > 0) { clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ; return ( num_error ) ;
}
// now check whether there is any bendline only face been created
// increase the part_numface if there is. int numregfaces = part_numface ; int numnewfaces = 0 ; if (maxnewfaces > 0) { for ( i = 0 ; i < maxnewfaces ; i++ ) { if (bendfacelist [i] .faceid <= 0) { numnewfaces = i + 1 ; break ;
}
} part_numface += numnewfaces ;
}
// first create a integer topological matrix to record all the topological relations int j ; imatrix = new int * fpart_numface] ; for ( i = 0 ; i < part_numface ; i++ ) { imatrix[i] = new int [part_numface] ; APPENDIX A
for ( j = 0 ; j < part_numface ; j ++ ) imatrix ti] [j ] = 0
} for ( i = 0 ; i < num_of_bendlines ; i++ ) {
// save the bendline entry + 1 in imatrix if (bendlinelist [i] .bendlineid) ( face_l = bendlinelist [i] . facel ; face_2 = bendlinelist [i] . face2 ; imatrix [face_l-l] [face_2-l] = i+1 ; imatrix [face_2-l] [face_l-l] = i+1 ;
} }
// from imatrix to find the number of bendlines of each face, nbl_face [i] ,
// and to verify that each face has at least one bendline nbl_face = new int [part_numface] ; for ( i = 0 ; i < part_numface ; i++ ) { nbl_face [i] = 0 ; for ( j = 0 ; j < part_numface ; j ++ ) { if ( imatrix ti] [j ] ) nbl_f ace ti] ++ ;
} if ( ! nbl_face [i] ) num_error++ ;
} if (num_error > 0 ) { clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) ; return ( num_error ) ;
}
// create the Cbpart' s topological matrix's input data FENT array
// and initialize it. part->get_name ( pname ) ; parrank = part_numface ; int spsize = parrank* (parrank + l)/2 + 1 ; // +1 is for End of FENT array indicator
FENT *sp = new FENT [ spsize ] ; for ( i = 0 ; i < spsize-1 ; i++ ) *(sp+i) = NoRelation ;
* (sp+spsize-1) = NullFent ;
10 APPENDIX A
// step 1: set up the positive or negative bend // The included FENT's are:
// * PosBend = + ; // positive bend between two faces
// * NegBend = ' - ' ; // negative bend between two faces
// * P90Bend = 'A' ; // 90 deg positive bend angle
// * N90Bend = 'B' ; // 90 deg negative bend angle
// MrPosBend = '3' ; // multiple positive bendlines between two faces
// MrNegBend = '4' ; // multiple negative bendlines between two faces
// * marks what is currently implemented, for ( i = 0 ; i < num_of_bend lines ; i++ ) { if (bendlinelist fi] .bendlineid) { face_l = bendlinelist fi] .facel ; face_2 = bendlinelist [i] . face2 ; FENT btype = NegBend ;
BM_BEND_OP_REGULAR * bendopr egu 1 ar
(BM_BEND_OP_REGULAR * ) bendlinelist [i] . bendoppt ; if (bendopregular->get_bend_type () ) btype = PosBend
double angle = bendopregular->get_bend_angle () ; if (angle > PI) {
// angle > PI => reverse bend direction and reset the bend angle angle = 2*PI - angle ; if (btype == PosBend) btype = NegBend ; else btype = PosBend ;
} bendlinelist [i] .bendangle = angle ; bendlinelist [i] .bendtype = btype ; // set up 90 degree bend type if (angle == PI_over_2) { if (btype == PosBend) btype = P90Bend ;
11 APPENDIX A
else btype = N90Bend ;
}
// set_FENT (sp, face_l, face_2, parrank, btype) ;
}
}
// step 2: set up the corner relationships, which is the relation
// between two faces that are connected to a common face.
// The included FENT are:
// * TouchCnr = 'T' ; // two faces same bend dir
// * OpenCnr = '0' ; // two faces same bend dir
// * PrllBend = 'P' ; // two parallel bendline same bend angle dir opposite bendline dir
// * SerlBend = 'S' ; // two parallel bendline same bend angle dir same bendline dir
// * cLnrBend = 'L' ; // colinear bendline same bend angle dir on one face
// * DfClnrBend = 'D' ; // colinear bendline same bend angle on different faces
// * tHkOffBend = 'H' ; // tHickness offset bendline same bend angle dir on two neighboring face
// * touchCnr = 't' ; // two faces opposite bend dir
// * openCnr = 'o' ; // two faces opposite bend dir
// * prllBend = 'p' ; // two parallel bendline opposite bend angle dir opposite bendline dir
// * serlBend = ' s' ; // two parallel bendline opposite bend angle dir same bendline dir
// * clnrBend = ' 1 ' ; // colinear bendline opposite bend angle dir on one face
// thkOffBend = 'h' ; // tHickness offset bendline opposite bend angle dir on two neighboring face
// * marks what is currently implemented.
12 APPENDIX A
// Algorithm : for every face that has more than one bend line then
// a pair of any two bend lines will have a relationship. for ( i = 0 ; i < part_numface ; i++ ) { if (nbl_face[i] > 1) { int face_c = i + 1 ;
// create a list of faces that are connected to this face for ( j = 0 ; j < part_numface ; j ++ ) { if ( imatrix f i] [j ] ) { int bl_l = imatri [i] [j ] ; face_l = j + 1 ; for ( int k = j +1 ; k < part_numface ; k++
) { if ( imatrix [i] [k] ) { int bl_2 = imatrix [i ] [k] ; face_2 = k + 1 ;
// define the relation ship between the two bendlines set bendline_rel FENT ( sp, parran ,
facelist, face_c, face_l, face_2,
bendlinelist, bl_l, bl_2, outfile) ;
} } } } } }
// * tHkOffBend = 'H' ; // tHickness offset bendline same bend angle dir on two neighboring face
// from imatrix to find the faces that may be of the thickness offset bendlines
// and verify these faces first based on the touch corner infomation then based on
// the bendlines' distance and parallel condition.
13 APPENDIX A
for ( i = 0 ; i < part_numface ; i++ ) { if ( nbl_face [i] < 2 ) continue ; // face i should have at least 2 bendlines for ( j = i+1 ; j < part_numface ; j++ ) { if ( ! imatrix [i] fj] | | nbl_face[j] < 2 ) continue ; // faces i and j must have a common bendline
// and face j should have at least 2 bendlines for ( int i2 = 0 ; i2 < part_numface ; i2++ ) { if ( !imatrixfi] fi2] | | i2 == j ) continue ; // faces i and i2 must have a common bendline
// and face i2 is different from j
// first requirement - bendlines imatrix[i] [j] and
// imatrixti] [i2] form a touch corner if ( get_FENT(sp, j+1, i2+l, parrank) !=
TouchCnr ) continue ; for ( int j2 = 0 ; j2 < part_numface ; 2++ )
{ if ( !imatrix[j] [J2] | | j2 == i ) continue
// second requirement - bendlines imatrix [i] [j] and
// imatrixtj] [j2] also form a touch corner if ( get_FENT(sp, i+1, j2+l, parrank) !=
TouchCnr ) continue
// comes here, we have obtained a candidate for the
// thickness offset bendlines, the two candidate
// bendlines are imatrix fi, i2] and imatrix[j] [j2] int bl_l = imatrixfi] [i2] ; int bl_2 = imatrix [j] [j2] ; check_thkoffbend ( sp, parrank, facelist, i+1, i2+l, j+1, 2+1, bendlinelist, bl_l, bl_2, thickness, outfile) ;
}
14 APPENDIX A
}
// DfClnrBend = 'D ; // colinear bendline same bend angle on different faces
// Here is to find all the colinear bends that are colinear but not related to each other // with a common face, int num_undetermined = 0 ;
UNDETERMINED *undetermined = new UNDETERMINED [num_of_bendlines] ;
UNDETERMINED *undetpt = undetermined ; for ( i = 0 ; i < num_of_bendlines ; i++ ) { if (bendlinelist fi] .bendlineid) { int face_il = bendlinelist [i] .facel , int face_i2 = bendlinelist [i] . face2 ; for ( j = i+1 ; j < num_of_bendlines ; j++ ) { if (bendlinelist [j] .bendlineid) { int face_jl = bendlinelist [j] . facel ; int face_j2 = bendlinelist fj] . face2 ; if ( face_il == face_jl | | face_il == face_j2 I I face_i2 == face_jl | | face_i2 == face_j2 ) continue ; if ( bendlinelist [j] .bendtype != bendlinelist [j] .bendtype ) continue ; if ( bendlinelist [j] .bendangle != bendlinelist [j] .bendangle ) continue ;
// come here when the two bend lines have the same bend angle and type,
// and they do not share a common face.
// now examine whether they are colinear int bl_i = i + 1 ; int bl_j = j + 1 ; int unknown = check_DfClnrBend ( sp, parrank, facelist, face_il, face_i2, face_jl, face_j2,
15 APPENDIX A
bendlinelis , bl_i, bl_j, part_numf ac e , imatrix, outfile) ; if (unknown) { undetermined[num_undetermined] .bendline_i = bl_i ;
undetermined[num_undetermined] .bendline_j = bl_j ; num_undetermined++ ,- } } } } }
// Note: if num_undetermined is not zero, then there are confirmed DfClnrBend
// but with undetermined faces for specify this FENT.
// A tree structure of all the faces that records the connectivity between
// faces need to be constructed. And then each pair of undetermined
// bendlines need to be processed to determine which two faces of the four
// that connected with the two bendlines should be used to record this FENT.
// Currently, we will neglect these information and simply delete
// undetermined array, which will not be used any more. delete [] undetermined ;
// transfer all the data back *inp_part_numface = part_numface *inp_parrank = parrank ; *inp_part_numbend = part_numbend *inp_part_maxface = part_maxface *inp_sp = sp ;
16 APPENDIX A
num_error = fclose (ou file) ; clean_up ( part_numface, imatrix, nbl_face, facelist, bendlinelist, bendfacelist) return ( num error ) ;
17 APPENDIX B
/////////////////////////////////////////////////////////////////
// / // Example of similarity index feature. Compares two parts // // topological matrix and search for their best similarity // // index. The similarity index is the summation of all the // // penalties of the mismatched FENTs of the two part's FENT // // matrix (topological matrix) . The best similarity index // // is the one with the smallest value. // // // // Copyright 1996 AmadaSoft America, Inc. // // //
////////////////////////////////////////////////////////////////// int matrix_similarity_index ( FENT *newmatrix, int newmatrixdim, int *newmatchlist, FENT *oldmatrix, int oldmatrixdim, int *oldmatchlist, int nfacefixed, int requiredvalue, int *minimumvalue) { //input
/ / newmatrix - new part topological matrix to be matched on
// by the oldmatrix
// newmatrixdim - matrix dimension of newmatrix
// newmatchlist - the first nfacefixed entries should
// contain the entries (faces) of the new part
// matrix that has already been fixed for
// matching with the old part matrix.
// oldmatrix - old part matrix to match with the new part
// topological matrix
// oldmatrixdim - matrix dimension of oldmatrix
// oldmatchlist - the first nfacefixed entries should
// contain the entries (faces) of the old part
// matrix that has already been fixed for
// matching with the new part matrix.
// nfacefixed the number of entries in matchlist that
// has already been matched,
Enter 0 when
// there is no prematched entries.
// requiredvalu< - the known or interested upper bound on the
// minimum similarity index.
When this value APPENDIX B
// is inputed as a positive value, then a
// branch of the search tree in finding the
// minimum value of the similarity index may
// be cut off when the branch's current value
// becomes greater than this minimum value.
// set to 0 or a negative value when there is
// no restriction. In this case, a minimumvalue
// and its corresponding macthlists will always
// be found and returned. //output
// newmat enlist the first nfacefixed entries should // contain the entries (faces) of the new part
// matrix that has already been fixed for
// matching with the old part matrix.
// oldmatchlist the first nfacefixed entries should
// contain the entries (faces) of the old part
// matrix that has already been fixed for
// matching with the new part matrix.
// minimumvalue the minimum similarity index, which is the
// smallest possible value of summation of all
// the penalties of the mismatched FENTs of the
// two part's FENT matrix (topological matrix) .
// This value may not exist, if the original
// inputed value (which is the requirement) is
// too small.
// return - index on whether or not found the minimum
// valu .
// = 1, found the minium value and its match. APPENDIX B
// = 0, a new minium value cannot be reached.
// = -1, error in the input data newmatchlist .
// = -2, error in the input data oldmatchlist.
// -3, error, the minimum similarity index of
// the given matrices are larger than the
// inputed minimumvalue.
/////////////////////////////////////////////////////////////////
// create two integer pointer arrays to keep track the
// corresponding entries of the two matrices that matches. int matrixdim = newmatrixdim ; if (matrixdim < oldmatrixdim) matrixdim = oldmatrixdim ; int *pnewmatchlist = new int [ matrixdim ] ; int *poldmatchlist = new int [ matrixdim ] ; if ( poldmatchlist && pnewmatchlist ) { int *pl = pnewmatchlist; int *p2 = poldmatchlist; for ( int icol = 1; icol <= matrixdim; icol++,pl++,p2++) *pl = *p2 = icol;
} else cout << "Unable to allocate memory..." << endl ;
// if there are already fixed entries (nfacefixed > 0) , then reset
// the temporary working pointer arrays (newmatchlist & oldmatchlist)
// to contain those fixed face list, if (nfacefixed > 0) { for (int icol = 0; icol < nfacefixed; icol++) { int iface = * (newmatchlist+icol) ; for ( int jcol = icol; jcol < matrixdim; jcol++) { if (iface == * (pnewmatchlist+jcol) ) { if (jcol != icol) {
* ( p n e w m a t c h l i s t + j c o l ) * (pnewmatchlist+icol) ;
* (pnewmatchlist+icol) = iface ; break ;
}
// comes here only if the inputed face number "iface"
// from newmatchlist is wrong APPENDIX B return (-1) ;
} iface = * (oldmatchlist+icol) ; for ( jcol = icol; jcol < matrixdim; jcol++) { if (iface == * (poldmatchlist+jcol) ) { if (jcol != icol) {
* ( p o l d m a t c h l i s t + j c o l ) * (poldmatchlist+icol ) ;
* (poldmatchlist+icol) = iface ;
} break ;
}
// comes here only if the inputed face number
"iface"
// from oldmatchlist is wrong return (-2) ;
}
// convert the FENT matrix to the counter part of integer matrix
// at the same time, expand the smaller matrix to have the same dimension. int *pnewmatrix = new int [matrixdim*matrixdim] ; int *poldmatrix = new int tmatrixdim*matrixdim] ; convert_fent_to_int (newmatrix, newmatrixdim, pnewmatrix, matrixdim) ; convert_fent_to_int (oldmatrix, oldmatrixdim, poldmatrix, matrixdim) ;
// define required value int requiredv = requiredvalue ; if (requiredv <= 0) requiredv = matrixdim * 400 ;
// create the FENT counters and use calculate_partial_similarity_index
// to calculate the initial similarity index and set the initial FENT
// counts for each column of the fixed faces and that of all the
// unfixed faces.
FENTCOUNT *pcnew = new FENTCOUNT[matrixdim+1] ;
FENTCOUNT *pcold = new FENTCOUNT [matrixdim+1] ; int currentvalue = calculate_partial_similarity_index ( pnewmatrix, pnewmatchlist, pcnew, poldmatrix, poldmatchlist, pcold, matrixdim, nfacefixed ) ; if (currentvalue > requiredv) return (-3) ;
// reset the unfixed faces in pnewmatchlist to be in the
4 APPENDIX B sequence of
// its total weighting. int ncandidates = matrixdim - nfacefixed ; int *pcandidates = new int [ncandidates] ; int *pweights = new int [ncandidates] ; for ( int i = 0 ; i < ncandidates ; i++ ) { int facenew = * (pnewmatchlist+nfacefixed+i) ;
* (pcandidates+i) = facenew ; int weight = 0 ; int *pnewi = pnewmatrix + (facenew-1) *matrixdim ; for ( int j = 0 ; j < matrixdim ; j++, pnewi++ ) weight += fent_weight (*pnewi) ;
* (pweights+i) = weight ; sort_the_candidates (pcandidates, pweights, ncandidates) ; for ( i = 0 ; i < ncandidates ; i++ )
* ( p n e wma t c h l i s t + n f a c e f i xe d + i ) =
* (pcandidates+ncandidates-1-i) ; delete [] pcandidates ; delete [] pweights ;
// call the internal routine recursively to perform similarity index
// search.
♦minimumvalue = requiredv ; int recursive_level = 0; int *newminmatchlist = new int [matrixdim] ; int *oldminmatchlist = new int [matrixdim] ; int *returnlevelcounts = new int [matrixdim] ; int errorcode = matrix_similarity_index_loop
( pnewmatrix, pnewmatchlist, newminmatchlist, poldmatrix, poldmatchlist, oldminmatchlist, pcnew, pcold, &currentvalue, matrixdim, nfacefixed,
&re curs ive_l eve 1 , minimumvalue, returnlevelcounts) ;
// clean up delete pnewmatchlist ; delete poldmatchlist ; delete pnewmatrix ; delete poldmatrix ; delete pcnew ; delete pcold ; delete returnlevelcounts delete newminmatchlist ; delete oldminmatchlist ; return (errorcode) APPENDIX B
}
////////////////////////////////////////////////////////////////// // extract the list of entries from an existing part matrix that matches
// with a new part matrix. The dimension of the part matrix must
// be greater then or equal to the dimension of the topological matrix.
// Note: The first element of matchlist must be initialized to
// contain the face number of the part matrix for macthing
// with the first face in the topological matrix.
// If nmatched is greater than 0, then the first nmatched
// entries in matchlist should contain positive numbers to
// indicate the already matched entries of the part matrix.
////////////////////////////////////////////////////////////////// int matrix_similarity_index_loop
( int *pnewmatrix, int *pnewmatchlist, int *newminmatchlist, int *poldmatrix, int *poldmatchlist, int *oldminmatchlist,
FENTCOUNT *pcnew, FENTCOUNT *pcold, int *currentvalue, int matrixdim, int nfacefixed, int
*recursive_leve1, int *minimumvalue, int *returnlevelcounts) { // input
// pnewmatrix - the new part's topological matrix, where
// the FENT contents have been changed to
// their representing integers. // (integer array of matrixdim * matrixdim)
// pnewmatchlist the list of entries of the newmatrix that
// has been matched by the oldmatrix.
// (integer array of matrixdim) // newminmatchlist - the list of entries of the newmatrix that
// has been matched by the oldmatrix that
// provides the minimum value. // (integer array of matrixdim) // poldmatrix - the old parts' s topological matrix, where
// the FENT contents have been changed to
// their representing integers, // (int array of matrixdim * matrixdim) // poldmatchlist the list of entries of the APPENDIX B oldmatrix that
// has matched with the newmatrix.
// (integer array of matrixdim)
// oldminmatchlist - the list of entries of the oldmatrix that
// has matched with the oldmatrix that
// provides the minimum value.
// (integer array of matrixdim)
// matrixdim - the matrix dimension of both matrices
// nfacematched - the number of entries (faces) that has
// been fixed in matching the two matrices .
// recursive_level - this keep the number of times this procedure
// has been called recursivly.
This provides a
// way to detect the error before going into a
// infinite loop. (integer pointer)
// output
// return - error index,
// = 0 means there is no error,
// > 0 error code.
//
// verify the recursive level if ( *recursive_level > matrixdim ) { cout << "??? Error - the recursive level is too high. ???\n"; cout << " The matrix dimension is " << matrixdim << "An"; cout << " The recursive level is " << *recursive_level << ".\n"; return (9) ; }
// Step 1) Choose a row to be matched with in the new matrix.
// ( Currently, it uses whatever the next row in line. Therefore,
// nothing to do at this moment.
// This may need to be changed to be properly matching up with
// the algorithm that may be used in defining the sequence of the
// candidate list.
// Note: If facenew is not next to the nfacefixed position, APPENDIX B then
// it should be changed to that position. ) int facenew = * (pnewmatchlist+nfacefixed) ;
// Step 2) Create a list of candidate face list in the old matrix.
// and calculate the increases in the similarity index for
// each of the candidates.
// ( Currently we are using what ever the sequence that is inside
// the poldmatchlist.
// One may choose to use the faces that at least matches up with
// the face connectivity of the chosen face in the new matrix.
// Note: The sequence of faces in pcandidates does not need to
// be corresponding to that in poldmatchlist. ) int ncandidates = matrixdim - nfacefixed ; int *pcandidates = new int [ncandidates] ; int *pincreases = new int [ncandidates] ; for ( int i = 0 ; i < ncandidates ; i++ ) { int faceold = * (poldmatchlist+nfacefixed+i) ; * (pcandidates+i) = faceold ; int increase = increase_on_similarity_index ( pnewmatrix, pnewmatchlist, facenew, poldmatrix, poldmatchlist, faceold, pcnew, pcold, currentvalue, matrixdim, nfacefixed, minimumvalue) ; * (pincreases+i) = increase ; }
// Step 3) Sort the candidate face based on the increased values
// the candidates with the lower increase will be tried first. sort_the_candidates (pcandidates, pincreases, ncandidates) ;
// Step 4) change the FENT counters of the newmatrix for fixing facenew int errorcode = change_counts_for_fix_one_face
( pnewmatrix, pnewmatchlist, facenew, pcnew, matrixdim, nfacefixed) ; if (errorcode != 0) return (errorcode) ;
// Step 5) Loop thru the candidate face and based on the increased value
// determines whether or not to continue to the lower level match.
8 APPENDIX B for ( int icandi = 0 ; icandi < ncandidates ; icandi++ ) ( // get the candidate face number of the old matrix and // its corresponding amount of increase on similarity index. int faceold = * (pcandidates+icandi) ; int increase = * (pincreases+icandi) ;
// Now check whether it is any need to continue the matching
// If the current value plus the increase has already exceed the
// minimum value, then there is no need to continue the matching.
// add the returnlevelcount and go to the next candidates. if (*currentvalue + increase >= *minimumvalue) { returnlevelcounts [nfacefixed] += 1 ;
} else if (nfacefixed+1 == matrixdim) {
// A new minimum similarity index has been found, update
// the minimum value
♦minimumvalue = *currentvalue + increase ; for ( i = 0 ; i < matrixdim ; i++ ) { newminmatchlist [i] = pnewmatchlist [i] ; oldminmatchlist [i] = poldmatchlist fi] ; }
} else {
// It is necessary to go down another level in this recursive
// call to define the similarity index.
// change the FENT counters of the oldmatrix for fixing faceold errorcode = change_counts_for_fix_one_face ( poldmatrix, poldmatchlist, faceold, pcold, matrixdim, nfacefixed) if (errorcode != 0) return (errorcode) ;
// call recursively currentvalue += increase ; *recursive_level += 1 ; errorcode = matrix_similarity_index_loop ( pnewmatrix, pnewmatchlist, newminmatchlist, poldmatrix, poldmatchlist, oldminmatchlist, APPENDIX B pcnew, pcold, currentvalue, matrixdim, nfacefixed+1, recursive_level, minimumvalue, returnlevelcounts) ; if (errorcode != 0) return (errorcode) ; ♦recursive_level -= 1 ; ♦currentvalue -= increase ;
// change the FENT counters of the oldmatrix for unfixing faceold change_counts_for_unfix_one_face ( poldmatrix, poldmatchlist, pcold, matrixdim, nfacefixed+1) ;
} }
// change the FENT counters of the newmatrix for unfixing facenew change_counts_for_unfix_one_face ( pnewmatrix, pnewmatchlist, pcnew, matrixdim, nfacefixed+1) ;
//clean up delete f] pcandidates ; delete U pincreases ; return (0) ;
////////////////////////////////////////////////////////////////// // updates counters for fixing one more face.
////////////////////////////////////////////////////////////////// int change_counts_for_fix_one_face
( int ♦pnewmatrix, int pnewmatchlist, int facenew,
FENTCOUNT ♦pcnew, int matrixdim, int nfacefixed) { // input
// pnewmatrix - the new part's topological matrix, where
// the FENT contents have been changed to
// their representing integers.
// (integer array of matrixdim matrixdim)
// pnewmatchlist the list of entries of the newmatrix that
// has been matched by the oldmatrix.
// (integer array of matrixdim)
10 APPENDIX B
// facenew - the face that is to be fixed. // pcnew - the FENTCOUNT of all the faces.
// matrixdim the matrix dimension of both matrices
// nfacematched - the number of entries (faces) that has
// been fixed in matching the two matrices .
// output
// pnewmatchlist the updated list of entries of the
// newmatrix matched by the oldmatrix,
// with the facenew entry is moved to the
// nfacefixed+1 location.
// pcnew - the updated FENTCOUNT of all the faces
// switch the to be fixed face to the location of nfacefixed+1 // in the pnewmatchlist int ifound = 0 ; for ( int i = nfacefixed ; i < matrixdim ; i++ ) { if (♦ (pnewmatchlist+i) == facenew) {
♦ (pnewmatchlist+i) = (pnewmatchlist+nfacefixed) ;
♦ (pnewmatchlist+nfacefixed) = facenew ; ifound++ ;
}
} if ( ifound != 1 ) { cout << "Fatal error from change counts for_fix one_face
/n' return ( 91 )
}
// define the pointer to the FENT on the to be fixed face int *pnewro = pnewmatrix + (facenew-1) ♦matrixdim ;
// first change the counters for the previously fixed faces for ( i = 0 ; i < nfacefixed ; i++ ) { int newcol = (pnewmatchlist+i) ; int pnewv = (pnewrow + newcol - 1) ; pcne [newcol] .count [pnewv] -- ; int igroup = fent_group (pnewv) ; pcnew[newcol] .gcount [igroup] -- ; if ( pcne [newcol] .count [pnewv] < 0 \ \ pcne [newcol] .gcount [igroup] < 0 ) { c o u t < < " F a t a l e r r o r f r o m change_counts_for_fix_one_face /n" ; return ( 92 ) ;
11 APPENDIX B
}
// second change the counters for the unfixed faces
// use count_specified_fents to initialize the FENTCOUNT of
// the newly seleted face and count the numbers of fents of
// the undetermined columns on the to be fixed rows int listdim = matrixdim - nfacefixed ; pcnew[facenew] = count_specified_fents ( pnewrow, pnewmatchlist+nfacefixed, matrixdim, listdim ) ;
// decrease the FENTCOUNT of the newly seleted face from that
// in remaining unfixed faces for ( i = 0; i < NumlntFent; i++ ) pcnew[0] .count [i] -= pcnew[facenew] .count [i] ; for ( i = 0; i < NumlntFentGroup; i++ ) pcne [0] .gcount [i] -= pcnew[facenew] .gcount [i] ; return (0) ;
////////////////////////////////////////////////////////////////// // This function updates the counters for release a fixed face. // The released face is the face currently on location nfacefixed.
////////////////////////////////////////////////////////////////// void change_counts_for_unfix_one_face
( int ♦pnewmatrix, int pnewmatchlist,
FENTCOUNT ♦pcnew, int matrixdim, int nfacefixed) { // input
/ / pnewmatrix - the new part's topological matrix, where
// the FENT contents have been changed to
// their representing integers.
// (integer array of matrixdim matrixdim)
// pnewmatchlist the list of entries of the newmatrix that
// has been matched by the oldmatrix.
// (integer array of matrixdim)
// pcnew - the FENTCOUNT of all the faces.
// matrixdim the matrix dimension of both matrices
// nfacematched - the number of entries (faces) that has
12 APPENDIX B
// been fixed in matching the two matrices.
// output
// pcnew - the updated FENTCOUNT of all the faces
// get the to be unfixed face number and
// define the pointer to the FENT on the to be fixed face int facenew = (pnewmatchlist+nfacefixed-1) ; int ♦pnewrow = pnewmatrix + (facenew-1) matrixdim ;
// first change the counters for the previously fixed faces for ( int i = 0 ; i < nfacefixed-1 ; i++ ) { int newcol = (pnewmatchlist+i) ; int pnewv = (pnewrow + newcol - 1) ; pcnew[newcol] .count [pnewv] ++ ; int igroup = fent_group (pnewv) ; pcnew[newcol] .gcount [igroup] ++ ;
}
// second change the counters for the unfixed faces by // adding the FENTCOUNT of the to be released face to that // of the remaining unfixed faces for ( i = 0; i < NumlntFent; i++ ) pcnew[0] .count [i] += pcnew[facenew] .count [i] ; for ( i = 0; i < NumlntFentGroup; i++ ) pcnew[0] .gcount [i] += pcnew[facenew] .gcount [i] ;
////////////////////////////////////////////////////////////////// // This function counts the number of FENTs in the given array of // intfent.
////////////////////////////////////////////////////////////////// FENTCOUNT count_fents ( int pintfentarray, int arraydim) { // input
// pintfentarray - the pointer to the intfent array
// arraydim - the dimension of the intfent array
// output
// return - FENTCOUNT, the FENT count of the
// input array
// define an FENT count and initialize it static FENTCOUNT fentc ; for ( int j = 0; j < NumlntFent; j++ ) fentc.count [j] = 0
13 APPENDIX B for ( j = 0; j < NumlntFentGroup; j++ ) fentc.gcount [j] = ^ ;
// Count the numbers of fents in an array of intfent for ( int *i = pintfentarray ; i < pintfentarray+arraydim ;
1 + + ) { fentc.count [*i] ++ ; fentc.gcount [fent_group(^i) ] ++ ; } return (fentc) ;
////////////////////////////////////////////////////////////////// // This function counts the number of FENTs in a specified set of
// an intfent array.
////////////////////////////////////////////////////////////////// FENTCOUNT count_specified_fents ( int pintfentarray, int ♦locationlist, int arraydim, int listdim) { // input
// pintfentarray - the pointer to the intfent array // locationlist - the locations in the intfent array
II that are to be included in counting
II arraydim - the dimension of the intfent array
II listdim - the dimension of the location list
II output
II return - FENTCOUNT, the FENT count of the
II selected elements in the input
// define an FENT count and initialize it static FENTCOUNT fentc ; for ( int j = 0; j < NumlntFent; j++ ) fentc.count [j] = 0 ; for ( j = 0; j < NumlntFentGroup; j++ ) fentc.gcount [j] = 0 ;
// Count the numbers of fents in an array of intfent for ( int +i = locationlist ; i < locationlist+listdim ,- i++
) { int intfent = (pintfentarray+ (^i) -1) ; fentc.count [intfent] ++ ; fentc .gcount [fent group (intfent) ] ++ ; } return (fentc) ;
14 APPENDIX B
////////////////////////////////////////////////////////////////// // This function counts the number of FENTs in a specified set of
// an intfent matrix.
// Note: The intfent matrix is symmetric. Only half of the matrix
// are included in the counting.
//////////////////////////////////////////////////////////////////
FENTCOUNT count_specified_fents_matrix ( int ♦pintfentmatrix, int ♦locationlist, int matrixdim, int listdim)
{ // input
// pintfentmatrix - the pointer to the intfent matrix // locationlist - the locations in the intfent matrix // that are to be included in counting
// matrixdim - the dimension of the intfent matrix // listdim - the dimension of the location list
// output
// return - FENTCOUNT, the FENT count of the
// selected elements in the input matrix
// define an FENT count and initialize it static FENTCOUNT fentc ; for ( int j = 0; j < NumlntFent; j++ ) fentc.count [j] = 0 ; for { j = 0; j < NumlntFentGroup; j++ ) fentc .gcount [j] = 0 ;
// Count the numbers of fents in an matrix of intfent for ( int i = 0 ; i < listdim ; i++ ) { int facenum = (locationlist+i) ; int pintfentrow = pintfentmatrix + (facenum 1) matrixdim ;
// Note: only half of the symmetric matrix is counted => // the k is atarted from i (diagonal included) . for ( int k = i ; k < listdim ; k++ ) { int intfent = (pintfentrow+ ( (locationlist+k) ) -1) ; fentc.count [intfent] ++ ; fentc.gcount [fent_group (intfent) ] ++ ;
} return (fentc) ;
}
////////////////////////////////////////////////////////////////// // This function returns the penalty on a mismatched pair of FENT.
15 APPENDIX B
////////////////////////////////////////////////////////////////// int penalty_of_fent_pair ( int intfentl, int intfent2) { // input
// intfentl - the intfent of part 1
// intfent2 - the intfent of part 2
// output
// return - the penalty for the mismatched intfents.
// No penalty, if they are the same if (intfentl == intfent2) return (0) ;
// add the penalty for mismatching the individual intfent int indexvalue = 0; indexvalue += fent_weight (intfentl) ; indexvalue += fent_weight (intfent2) ;
// add the penalty for mismatching their fent group int fentgroupl = fent_group (intfentl) ; int fentgroup2 = fent_group(intfent2) ; if (fentgroupl 1= fentgroup2) { indexvalue += fent_group_weight (fentgroupl) ; indexvalue += fent group weight (fentgroup2) ;
} return (indexvalue)
}
////////////////////////////////////////////////////////////////// // This function returns the minimum penalty for the least possible // mismatches of two FENTCOUNT.
////////////////////////////////////////////////////////////////// int penalty_of_FENTCOUNT_jpair ( FENTCOUNT const fcfentcountl,
F E N T C O U N T c o n s t
&fentcount2 ) { / / input
// fentcount1 - the FENTCOUNT of part 1
// fentcount2 - the FENTCOUNT of part 2
// output
// return - the minimum penalty on the mismatches
// of two FENTCOUNTS.
// Now loop thru the FENTCOUNT,
// currently method uses the penalty of the minimum possible
// individual mismatches as the penalty plus the penalty of
// the minimum possible mismatched groups int indexvalue = 0; for ( int i = 1; i < NumlntFent; i++ )
16 APPENDIX B if ( fentcountl .count [i] != fentcount2.count [i] ) indexvalue += fent_weight (i) abs ( fentcountl . count [i] f ent count 2.count [i] ) ; for ( i = 1; i < NumlntFentGroup; i++ ) if ( f entcountl. gcount [i] != fentcount2.gcount ti] ) indexvalue += fent_group_weight (i) abs ( fentcountl . gcount [i] fentcount2.gcount [i] ) ; return (indexvalue) ; }
////////////////////////////////////////////////////////////////// // This function returns the penalty on a mismatched pair of FENT.
////////////////////////////////////////////////////////////////// int change_from_seperate_fent_sets ( int ntnew, int ntold, int nsnew, int nsold
)
{ // input
// ntnew - number of FENT in the whole set of the new part .
// ntold - number of FENT in the whole set of the old part .
// nsnew - number of FENT in the sub-set of the new part.
// nsold - number of FENT in the sub-set of the old part.
// output
// return - the change in the number of counts of the mismatch
// due to the separation of the sub-set from the
// whole set. int difforg = abs ( ntnew-ntold ) ; int diffsub = abs ( nsnew-nsold ) ; int diffnew = abs ( ntnew-nsnew-ntold+nsold ) ,- int change = diffsub + diffnew - difforg ; return ( change ) ;
/////////////////////////////////////////////////////// / / This function returns the minimum penalty for the least possible // mismatches of two FENTCOUNT.
////////////////////////////////////////////////////////////////// int increase_from_separate_a_pair_of_fent (
FENTCOUNT const &pcnew_total, FENTCOUNT c on s t &pcold_total, int intfentnew_separ, int intfentold_separ )
17 APPENDIX B
// input
// pcnew_total - the total FENTCOUNT of the new part
// pcold_total - the total FENTCOUNT of the old part
// intfentnew_separ - to be seperated FENT of the new part
// intfentold_separ - to be seperated FENT of the old part
// output
// return - the increase in the penalty due to the
// seperation of the FENTs. static int ntnew, ntold, igroup ; static int increase ; if (intfentnew_separ == intfentold_separ) { ntnew = pcnew_total.count [intfentnew_separ] ; ntold = pcold_total .count [intfentnew_separ] ; increase = fent_weight (intfentnew_separ) change_from_seperate_fent_sets (ntnew, ntold, 1, l ) igroup = fent_group (intfentnew_separ) ; ntnew = pcnew_total.gcount [igroup] ; ntold = pcold_total.gcount [igroup] ; increase += fent_group_weight (igroup) change_from_seperate_fent_sets (ntnew, ntold, 1,
1 ) else ( ntnew = pcnew_total.count [intfentnew_separ] ; ntold = pcold_total.count [intfentnew_separ] ; increase = fent_weight (intfentnew_separ) change_from_seperate_fent_sets (ntnew, ntold, 1,
0 ) ntnew = pcnew_total.count [intfentold_separ] ; ntold = pcold_total.count [intfentold_separ] ; increase += fent_weight (intfentold_separ) change_from_seperate_fent_sets(ntnew, ntold, 0, l ) ; i f ( f e n t _ g r o u p ( i n t f e n t n e w _ s e p a r ) = = fent_group (intf entold_separ) ) { igroup = fent_group (intf ntnew_separ) ; ntnew = pcnew_total .gcount [igroup] ; ntold = pcold_total.gcount [igroup] ; increase += fent_group_weight (igroup) change_from_seperate_fent_sets (ntnew, ntold, 1, 1 ) ;
} else { igroup = fent_group(intfentnew_separ) ;
18 APPENDIX B ntnew = pcnew_total.gcount [igroup] ; ntold = pcold_total.gcount [igroup] ; increase += fent_group_weight (igroup) change_from_seperate_fent_sets (ntnew, ntold, 1, 0 ) ; igroup = fent_group (intfentold_separ) ; ntnew = pcnew_total.gcount [igroup] ; ntold = pcold_total .gcount [igroup] ; increase += fent_group_weight (igroup) change_from_seperate_fent_sets (ntnew, ntold, 0, 1 ) ; }
} return (increase) ;
}
////////////////////////////////////////////////////////////////// // This function returns the minimum penalty for the least possible // mismatches of two FENTCOUNT.
////////////////////////////////////////////////////////////////// int increase_from_separate_a_pair_of_fentcount (
FENTCOUNT const &pcnew_total, FENTCOUNT c on s t &pcold_total,
FENTCOUNT const &pcnew_separ, FENTCOUNT c on s t &pcold_separ ) { // input
// pcnew_total - the total FENTCOUNT of the new part
// pcold_total - the total FENTCOUNT of the old part
// pcnew_separ - to be seperated FENTCOUNT of the new part
// pcold_separ - to be seperated FENTCOUNT of the old part
// output
// return - the increase in the penalty due to the
// seperation of the FENTCOUNTs.
// Now loop thru the FENTCOUNT,
// currently method uses the penalty of the minimum possible
// individual mismatches as the penalty plus the penalty of
// the minimum possible mismatched groups int change, increase ; increase = 0; for ( int i = l; i < NumlntFent; i++ ) { change = change_from_seperate_fent_sets ( p c n e w _ t o t a l . c o u n t [ i ] , ρcold_total . count [i] , pcnew_separ . count [i] , pcold_separ . count [i] ' ;
19 APPENDIX B if ( change != 0 ) increase += fent weight (i) change ; } for ( i = 1; i < NumlntFentGroup; i++ ) { change = change_from_seperate_fent_sets ( p c n e w _ t o t a l . g c o u n t [ i ] , pcold_total . gcount [i] , p c n e w _ s e p a r . g c o u n t [ i ] , pcold_separ .gcount [i] ) ; if ( change != 0 ) increase += fent_group_weight (i) change ; } return (increase) ;
////////////////////////////////////////////////////////////////// // This function calculates the similar index for the given set of
// faces up to the specified fixed faces.
// Note: only half of the matrix are included in the calculation.
////////////////////////////////////////////////////////////////// int direct_calculate_similarity_index
( int pnewmatrix, int pnewmatchlist, int ♦poldmatrix, int poldmatchlist, int matrixdim)
{
// loop thru the faces and calculate the similarity index int indexvalue = 0 ; for (int iface = 0; iface < matrixdim; iface++) { int facenew = (pnewmatchlist+iface) ; int faceold = (poldmatchlist+iface) ; int pnewrow = pnewmatrix + (facenew - 1) matrixdim ; int poldrow = poldmatrix + (faceold - 1) matrixdim ;
II first from the mismatches of the fixed faces.
II Note: the diagonal terms of the matrix are always iNoRelation.
// therefore, they are skip in the loop. // also due to the symmetry, only half of the matrix are
// included in the calculation of the similarity index for (int icol = iface; icol < matrixdim; icol++) ( int newcol = (pnewmatchlist+icol) int oldcol = (poldmatchlist+icol) int pnewv = (pnewrow + newcol - 1) int poldv = (poldrow + oldcol - 1) if ( pnewv != poldv ) indexvalue penalty_of fent_pair (pnewv,poldv) ;
20 APPENDIX B
} return (indexvalue) ;
////////////////////////////////////////////////////////////////// // This function calculates the similar index for the given set of // faces up to the specified fixed faces.
////////////////////////////////////////////////////////////////// int calculate_partial_similarity_index
( int ♦pnewmatrix, int pnewmatchlist, FENTCOUNT ♦pcnew, int ♦poldmatrix, int poldmatchlist, FENTCOUNT pcold, int matrixdim, int nfacefixed)
// loop thru the faces and calculate the similarity index int indexvalue = 0 ; for (int iface = 0 ; iface < nfacefixed; iface++) { int facenew = (pnewmatchlist+iface) ; int faceold = (poldmatchlist+iface) ; int *pne row = pnewmatrix + (facenew - 1) ♦matrixdim ; int poldrow = poldmatrix + (faceold - 1) matrixdim ;
// first from the mismatches of the fixed faces. // Note: the diagonal terms of the matrix are always iNoRelation.
// therefore, they are skip in the loop. // also due to the symmetry, only half of the matrix are
// included in the calculation of the similarity index for (int icol = iface ; icol < nfacefixed; icol++) { int newcol = (pnewmatchlist+icol) ; int oldcol = (poldmatchlist+icol) ; int pnewv = (pnewrow + newcol - 1) ; int poldv = ♦(poldrow + oldcol - 1) ; if ( pnewv != poldv ) indexvalue += penalty_of fent_pair(pnewv,poldv) ;
// use count_specified_fents to initialize the FENTCOUNT of
// the facenew and faceold and to count the numbers of fents of
// the columns of the unfixed faces int listdim = matrixdim - nfacefixed ; pcnew[facenew] = count_specified_fents ( pnewrow, pnewmatchlist+nfacefixed, matrixdim, listdim ) pcold[faceold] = count_specified_fents ( poldrow, poldmatchlist+nfacefixed, matrixdim, listdim )
21 APPENDIX B
// Now loop thru the FENTCOUNT of the facenew and faceold // and calculate the penalty of their mismatches. indexvalue += penalty_of_FENTCOUNT_pair ( pcnew[facenew] , pcold[faceold] ) ;
// use count_specified_fents_matrix to get the FENTCOUNT
// of the unfixed faces of both matrices int listdim = matrixdim - nfacefixed ; pcne [0] = count_specified_fents_matrix ( pnewmatrix, pnewmatchlist+nfacefixed, matrixdim, listdim ) ; pcold[0] = count_specified_fents_matrix ( poldmatrix, poldmatchlist+nfacefixed, matrixdim, listdim ) ;
// Finally calculate the penalty of the FENTCOUNT // of the unfixed faces of the two matrices, indexvalue += penalty_of_FENTCOUNT_pair ( pcnew[0] , pcold[0]
) ;
// Return the amount of penalty on the two partially fixed // part matrices as its minimum possible similarity index, return (indexvalue) ;
////////////////////////////////////////////////////////////////// // This function calculates the increase in the similar index for // the mismatches of the given facenew and faceold.
////////////////////////////////////////////////////////////////// int increase_on_similarity_index
( int ♦pnewmatrix, int pnewmatchlist, int facenew, int ♦poldmatrix, int poldmatchlist, int faceold, FENTCOUNT ♦pcnew, FENTCOUNT pcold, int currentvalue, int matrixdim, int nfacefixed, int minimumvalue)
{
// loop thru the faces to see how much increase is in the
// current value. int increase = 0 ; int pnewrow = pnewmatrix + (facenew-1) matrixdim ; int poldrow = poldmatrix + (faceold-1) matrixdim ;
// first loop thru the previously fixed faces and calculate // the increase for the mismatches between the chosen columns for ( int i = 0; i < nfacefixed; i++ ) { int newcol = (pnewmatchlist+i) ; int oldcol = (poldmatchlist+i) ;
22 APPENDIX B int pnewv = (pnewrow + newcol - 1) ; int poldv = ♦ (poldrow + oldcol - 1) ; if ( pnewv ! = poldv ) {
FENTCOUNT pcnewcol = pcnew[newcol] ;
FENTCOUNT pcoldcol = pcold[oldcol] ; increase += increase_from_separate_a_pair_of_fent ( pcnewcol, pcoldcol, pnewv, poldv ) ;
}
}
// use count_specified_fents to initialize the FENTCOUNT of
// the newly seleted face and count the numbers of fents of
// the undetermined columns on the to be fixed rows int listdim = matrixdim - nfacefixed ; pcnew[facenew] = count_specified_fents ( pnewrow, pnewmatchlist+nfacefixed, matrixdim, listdim ) ; pcold[faceold] = count_specified_fents ( poldrow, poldmatchlist+nfacefixed, matrixdim, listdim ) ; increase += increase_from_separate_a_pair_of_fentcount ( pcnew[0] , pcold [0] , pcnew [facenew] , pcold[faceold]
// Return the amount of increase in the similarity index for // the matching of the chosen two faces, facenew in new part // and the faceold in the old part . return (increase) ;
23 APPENDIX C
1/ II
II Example of bendline detection with comments. This module // // contains BM_PART: :auto_bend() implementation. //
// //
// Copyright 1996 AmadaSoft America, Inc. //
// //
111111 U 11111111111111111111111111 ! 11111 n I n 111 ! 111111 ! 111 ! 11111
/ *
*********** ********** ********** ********** *********** ********* This is a major high-level Bend Model function for part design and construction. Its purpose is to create bendlines between faces so that the part becomes connected (if possible) .
This function was created to facilitate part creation. Normally, a third-party CAD program is used to draw a part. Since Bend Model does not have any control over the CAD system, for our purposes this drawing is just a set of edges. Therefore this drawing has to be analyzed in order to detect the structure of the part. After that we can create faces and bendlines of the part. However, the input drawing is often ambigious - bendlines are not uniquely defined. In that case we use a number of heuristics to create bendlines. This heuristics define preference criterias for picking one outcome when many are possible.
Since this problem is common to many applications this function is part of the Bend Model. Moreover, implementing this function in Bend Model will simplify the face detection software that has to be part of the CAD system. In this function we assume that edges of faces are sorted according to the left-hand side rule in a way that is consistent with the plane normal (which defines the plane orientation) . Basically, this function assumes that every plane is correct by itself, when viewed in isolation. However, this function does not require that the orientation of adjacent planes be correct with respect to the bendlines between them (there is a Bend Model function for fixing that later) .
This function can be used to generate bendlines for both 3D-version of the part and the flat version of the part. However, the part can have either the flat or 3D version, but not both. In other words, either all 3D-version of 3D-bodies must be NULL (in which case we have a flat version) , or all flat versions must be NULL. */ APPENDIX C
*********** ********** ********** ********** ********** **** ***** Algorithm/Process :
The objective of the algorithm is the create a minimum number of bendlines (because we want to change the part as little as possible) so that the entire part becomes connected (ie. all faces all connected via bendlines - we don't want any stand-alone faces hanging around), given the restriction that we don't create loops in the topology graph of the part.
It is not required that the input part contain no bendlines. AutoBend takes into account existing bendlines and adds new bendlines to the part. On the top level, this algorithm performs a version of the maximum spanning tree algorithm.
At any point in time, it has a current connected component and a set of fringe faces (that are part of the connected component) . These fringe faces have contacts with faces outside of the connected component. During one iteration, one new face that is outside of the connected component will be added to the connected component . Among the faces outside the connected component that are in contact with a fringe face, AutoBend picks one that has the largest contact .
This heuristic of using the largest contact is based on the fact that in sheet-metal manufacturing, the larger the contact the better, usually. However, when there is a tie - ie. there are several faces outside the connected component that have the same largest contact with a fringe face in the connected component, we use another heuristic. This heuristic picks a face that would minimize the diameter of the part . The diameter of the part is the largest distance between any two faces in the topology graph of the part.
*********** ********** ********** ********** ********** **********
Technical notes :
- This function probably does not work well if the part thickness is not zero.
- Note that this function creates bendline information that is consistent with facel in the algorithm (mainly, facel normal) . However, face2 normal can be inconsistent with this information, but that has to be fixed later.
See comments in PART.HXX.
********** ********** ********** ********** ********* ********* */ APPENDIX C
#include <stdio.h> #include <stdlib.h>
#include "GLOBAL.HXX" #include "ENTITY.HXX" #include "PLANE.HXX" ^include "CYLINDER.HXX" #include "LINE.HXX" #include "LOOP.HXX" #include "2D_BODY.HXX" #include "FORMING.HXX" #include "FACE.HXX" #include "BEND_OP_R.HXX" #include "BEND_PRP.HXX" #include "BENDLINE.HXX" #include "PART.HXX" #include "DBM.HXX"
/*
This function computes all contacts between the given two faces.
A contact is when two faces are touching each other (ie. within some very small distance tolerance) and the line separating them has length greaterthan 0 (ie. the common line is not a point, but a real line) .
Purpose :
To compute a list of potential bendlines between given two faces.
Assumptions :
- both faces have a non-NULL 3D version that is up to datewhich will be used for the computation.
- all loops in either faces are closed.
Requirements :
- both faces must be in the same part. Returns :
- a list of contacts
This returned list has a structure : node 0 : obj is "number of contacts" node 2i-l : obj is "head of the list on facel side, of
3 APPENDIX C
contact i" node 2i : obj is "head of the list on face2 side, of contact i" where i is in [1, "number of contacts"] .
Note that each contact is a "closed" contact, ie . there are no gaps in the contact.
Each list on either side of the contact is a list of lines (actually pointers to lines) such that the order of lines in the list is opposite to sweep direction (currently XZY sweep) .
This is what a list of contacts looks like :
# of contacts -> listl .facel .head -> listl .face2.head -> ... -> list i. facel.head -> list i.face2.head.
I I
I I
I !
V V
V V linel in facel linel in face2 linel in facel linel in face2
I I I I
I I
V V
V V
I I
V V
V V line i in facel line j in face2 line k in facel line 1 in face2
Note that in this function a co-linear bendline of k bends is considered as k separate contacts.
Notes :
- By default we will consider all lines in both faces as candidates for a bendline.
However, if the user already known what the bendline is (or actually, knows what the bendline APPENDIX C
edges are) he can use the name of these lines to instruct this function to consider only those lines. This function will check if any of the lines in facel or face2 (faces 1 and 2 are checked separately) have a name that is euqal to the idx of the other face. If yes, only these lines will be considered as candidates for a bendline on the side of that face.
*/ static int BM_compute_all_face_to_face_contacts ( BM_FACE & facel / IN /, BM_FACE & face2 / IN /, BM LINKED_LIST_NODE ♦♦list_of_contacts / OUT /)
{
// initialize global variables.
// this is the contacts list we will be computing, initially list is NIL.
♦list_of_contacts = NULL ;
// this points to the beginning of the contacts list. // it does not contain the number of contacts. // ie. points to "list_of_contacts [1] " . BM_LINKED_LIST_NODE contacts = NULL ; double line_start_coordinates = NULL ; // used when the set of lines is sorted
BM_LINE ♦♦line_pointers = NULL ; // an array of lines (actually pointers to lines) used to store
// lines being swept.
// once lines are sorted according to the XZY order, we will scan this array from the end
// to the beginning -> this implements the sweep.
// at the same time, we maintain a list of open lines, this is done by leaving line
// pointers in this array "behind" as they are when we move forward in the array.
// to erase a line from the open list, we simple set the pointer in the array to NULL.
// endpoints of lines in facel and face2 that are larger with respect to XZY ordering.
// used when processing contacts. BM_POINT p_facel, p_face2 ;
// some variables used in many places, long i, j ; BM_POINT p ; APPENDIX C
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Qualification check.
********** ********** ********** ********** **********
********** ********** ********** **********
*/
// both faces must be in the same part if (facel.get_part () == NULL | | facel .get_part () != face2.get_part () ) return 0 ; d o u b l e l o c a l _ t o l e r a n c e =
(facel . get_part ( ) ) - >get_distance_tolerance ( ) ;
// first try 3D-versions of faces, if both of them are empty, try flat versions.
BM_2D_B0DY bodyl = facel .get_current_3D_version () ; BM_2D_B0DY ♦body2 = face2.get_current_3D_version() ; if (NULL == bodyl && NULL == body2) { bodyl = facel .get_flat () ; body2 = face2.get flat() ;
} // if either of the 3D-bodies is NULL we are successfully done. if (NULL == bodyl | | NULL == body2) return 1 ;
// both faces must have a plane as the underlying surface BM_SURFACE surf acel = bodyl ->get_surf ace { ) ; BM_SURFACE ♦surface2 = body2->get_surf ace ( ) ; if (NULL == surface2 | j NULL == surface2) return 0 ; if ( ! sur f ace2 - > is ( BM_T Y P E_ P L ANE ) | j ! surface2->is (BM_TYPE_PLANE) ) return 0 ;
// if any of the faces has an empty bloop, we are successfully done
BM_L00P bloopl = bodyl - >get_bloop ( ) ; BM_LOOP bloop2 = body2->get_bloop ( ) ; if (NULL == bloopl ] | NULL == bloop2) return 1 ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Here we will do a very quick check if these faces can be in contact at all.
Here we check if bloop of face2 touches (at more than one point) or intersects the plane of facel.
This will save some time when these two faces obviously cannot be in contact.
********** ********** ********** ********** ********** APPENDIX C
********** ********** ********** ********** */
// these variables will be used to do a quick check if these t o
// faces can possible touch each other double distance_plane_to_bloopl, distance_plane_to_bloop2, distance_plane_to_bloop3, distance_plane_to_bloop4 ; int distance_plane_to_bloop_count ; if (! bloop2->is_bbox_up_to_date () ) bloop2->recompute__bbox() i f (
BM_distance_between_point_and_plane (bloop2->get_bbox_pl () ,
(BM_PLANE&) (surfacel) , &distance_plane_to_bloopl NULL) ) return 0 ; i f (
BM_distance_between_point_and_plane (bloop2->get_bbox_p20 ,
(BM_PLANE&) (surfacel) , &distance_plane_to_bloop2 NULL) ) return 0 ; i f (
BM_distance_between__point_and_plane (bloop2->get_bbox_p30 ,
(BM_PLANE&) (surfacel) , &distance_plane_to_bloop3 NULL) ) return 0 ; i f (
BM_distance_between_point_and_plane (bloop2->get_bbox_p4 () ,
(BM_PLANE&) (surfacel) , &distance_plane_to_bloop4 NULL) ) return 0 ; distance_plane_to_bloop_count = 0 ; if (fabs (distance_plane_to_bloopl) >= local_tolerance) distance_plane_to_bloop_count++ ; if (fabs (distance_plane_to_bloop2) >= local_tolerance) distance_plane_to_bloop_count++ ; if (fabs (distance_plane_to_bloop3) >= local_tolerance) distance_plane_to_bloop_count++ ; if (fabs (distance_plane_to_bloop4) >= local_tolerance) distance_plane_to_bloop_count++ ; if (distance_plane_to_bloop_count > 2) {
// at most one of the bloop corners is on the plane. // that means, bbox itself is not in contact with facel. // however, it could be that different corners of bbox are on different sides of the plane.
// here we will return if all bloop2 points are on one side of planel
// ie. these two faces cannot be in contact
//
// note : at most one of the 4 distance_plane_to_bloop-i can be zero.
//
// in the next line we pick "distance_plane_to_bloopl" APPENDIX C
for checking not because it is special,
// but because any of the 4 would do. if (fabs (distance_plane_to_bloopl) >= local_tolerance) { i f
(distance_plane_to_bloopl+distance_plane_to_bloop2 >= 0.0 && distance_plane_to_bloopl^distance_plane_to_bloop3 >= 0.0 && distance_plane_to_bloopl^distance_j?lane_to_bloop4 >= 0 . 0 ) return 1
else { i f
(distance_plane_to_bloop2^distance_plane_to_bloop3 >= 0.0 && distance_plane_to_bloop2^distance_plane_to_bloop4 >= 0.0) return 1
}
} // if the count is 0, 1 or 2, it means that 2, 3 or 4 bbox corners are on the plane.
// that means, it is possible that there is a contact.
/*
Now we check the same thing for bboxl with respect to face2.
*/ if (! bloopl->is_bbox_up_to_date () ) bloopl->recompute_bbox () i f ( !
BM_distance_between_point_and_plane (bloopl->get_bbox_pl () ,
(BM_PLANE&) (surface2) , &distance_plane_to_bloopl, NULL) ) return 0 ; i f ( !
BM_distance_between_point_and_plane (bloopl->get_bbox_p2 () ,
(BM_PLANE&) (surface2) , &distance_plane_to_bloop2, NULL) ) return 0 ; i f ( !
BM_distance_between_point_and_plane (bloopl->get_bbox_p3 () ,
(BM_PLANE&) (surface2) , Scdistance_plane_to_bloop3, NULL) ) return 0 ; i f ( !
BM_distance_between_point_and_plane (bloopl->get_bbox_p4 () ,
(BM_PLANE&) (surface2) , &distance_plane_to_bloop4, NULL) ) return 0 ; distance_plane_to_bloop_count = 0 ; if (fabs (distance_plane_to_bloopl) >= local_tolerance) distance_plane_to_bloop_count++ ; if (fabs (distance_plane_to_bloop2) >= local_tolerance) distance_plane_to_bloop_count++ ;
8 APPENDIX C
if (fabs (distance_plane_to_bloop3) >= local_tolerance) distance_plane_to_bloop_count++ ; if (f bs (distance_plane_to_bloop4) >= local_tolerance) distance_plane_to_bloop_count++ ; if (distance_plane_to_bloop_count > 2) {
// at most one of the bloop corners is on the plane. // here we will return if all bloopl points are on one side of plane2
// ie. these two faces cannot be in contact if (fabs (distance_plane_to_bloopl) >= local__tolerance) { i f
(distance_plane_to_bloopl+distance_plane_to_bloop2 >= 0.0 && distance_plane_to_blooplΛdistance_plane_to_bloop3 >= 0.0 && distance_plane_to_bloopl^distance_plane_to_bloop4 >= 0.0) return 1 ; else { i f
(distance_plane_to_bloop2^distance_plane_to_bloop3 >= 0.0 && distance_plane_to_bloop2^distance_plane_to_bloop4 >= 0.0) return 1 ;
) J
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Count the total number of lines in both faces. We need to allocate memory.
Note : we only count edges that are lines, because only lines can make bendlines.
Note : we will check if the user has specified bend edges. User can restrict which edges will be considered as possible bend edge by setting the name of those edges.
********** ********** ********** ********** **********
********** ********** ********** **********
*/ long facel_has_user_defined_bend_edges = 0 ; // the number of user-speicifed bend edges in facel long face2_has__user_defined_bend_edges = 0 ; // the number of user-speicifed bend edges in face2 long facel_line_count = 0, face2_line_count = 0 ; long line count ; // sum of lines in faces 1 and 2 APPENDIX C
participating in the sweep. BM_LOOP holes ; BM_EDGE edges ; for (edges = bloopl->get_first_edge () ; edges ; edges = (BM_EDGE ) edges->next () ) { if (! edges->is(BM_ENTITY_TYPE_LINE) ) continue ; if (edges- >get_name ( ) == face2. get_idx ( ) ) facel_has__user_defined_bend_edges++ ; facel line count++ ;
} for (holes = bodyl->get_first_hole () ; holes ; holes =
(BM_LOOP ) holes->next () ) { for (edges = holes->get_first_edge () ; edges ; edges = (BM_EDGE ) edges->next () ) { if (! edges->is(BM_ENTITY_TYPE_LINE) ) continue ; if (edges->get_name () == face2.get_idx() ) facel__has_user_defined_bend_edges++ ; facel line count++ ;
} ~ "
} for (edges = bloop2->get_first_edge () ; edges ; edges =
(BM_EDGE ♦ ) edges - >next ( ) ) { if ( ! edges- >is (BM_ENTITY_TYPE_LINE) ) continue ; i f ( edge s - >ge t_name ( ) = = f acel . get_idx ( ) ) face2_has_user_def ined_bend_edges++ ; face2 line count++ ;
} ~ " for (holes = body2->get_first_hole () ; holes ; holes =
(BM_LOOP ) holes->next () ) { for (edges = holes->get_first_edge () ; edges ; edges =
(BM_EDGE ) edges->next () ) { if (! edges->is(BM_ENTITY_TYPE_LINE) ) continue ; if (edges->get_name () == facel.get_idx() ) face2_has_user_defined_bend_edges++ ; face2 line count++ ;
// if there are no lines, we are successfully done if (facel_has_user_defined_bend_edges) facel_line_count facel_has_user_defined_bend_edges ; if (face2_has_user_defined_bend_edges) face2_line_count face2_has_user_defined_bend_edges ; if (facel_line_count < 1 | | face2_line_count < 1) return 1 ; line_count = facel_line_count + face2_line_count ;
/*
********** ********** ********** ********** **********
********** ********** ********** ********** Allocate memory.
10 APPENDIX C
********** ********** ********** ********** ********** ********** ********** ********** **********
*/ if (NULL == (line_pointers = new BM_LINE+ [line_count] ) ) return
0 ; if (NULL == (line_start_coordinates = new double [line count] ) )
{ delete [] line_pointers ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
First, fill in the line pointers array.
If required, take only user-specified edges.
********** ********** ********** ********** **********
********** ********** ********** **********
*/
Figure imgf000222_0001
11 APPENDIX C
edges->get_name () != facel.get_idx() ) continue ; line pointers [i++] = (BM LINE ) edges ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Sort the array of lines by X-coordinate, then by Z-coordinate and then by Y.
********** ********** ********** ********** **********
********** ********** ********** **********
*/
{ // this is a block of code for sorting the array
// first, construct the array of points and lines associated with them for (i = 0 ; i < line_count ; i++) {
P BM_get_greater_point_by_XZY( (line_pointers [i] ) ->get_startpt () , (li ne_pointers ti] ) ->get_endpt () ) ; line start coordinates [i] = p.X() ;
} " // sort by X
DBM_QuickSort_double ( line_start_coordinates , line_count , ( long ) line_pointers ) ;
// sort by Z double first_in_set_Z = line_start_coordinates [0] ; long set_Z_size = 1, first_in_set_Z_idx = 0 ;
P BM_get_greater_point_by_XZY( (line_pointers [0] ) ->get_startpt () , (li ne_pointers [0] ) ->get_endpt () ) ; line_start_coordinates [0] = p.Z() ; for (i = 1 ; i <= line_count ; i++) { if (i < line_count) { li {
Figure imgf000223_0001
i f ( s e t _ Z _ s i z e > l ) DBM_QuickSort_double (line_start_coordinates + first_in_set_Z_idx, set_Z_size, (long ) line_pointers +
12 APPENDIX C
f irst_in_set_Z_idx) ;
// sort by Y long set_Z_end = f irst__in_set_Z_idx + set_Z_size ; d o u b l e f i r s t _ i n _ s e t _ Y line_start_coordinates [f irst_in_set_Z_idx] ; long set_Y_size = 1, f irst_in_set_Y_idx f irst_in_set_Z_idx ;
B M _ P 0 I N T pY (BM_get_greater_point_by_XZY ( (line_pointers [f irst_in_set_Z_idx] ) ->get_startpt () , (line_pointers [f irst_in_set_Z_idx] ) ->get_endpt () ) ) line_start_coordinates [f irst_in_set_Z_idx] = pY.YO ; for (j = f irst_in_set_Z_idx + 1 ; j <= set Z end ; j++)
{ if (j < set_Z_end) { p Y
BM_get_greater_point_by_XZY ( (line_pointers fj] ) ->get_startpt () , (li ne_pointers [ j ] ) - >get_endpt ( ) ) ; if ( 1 i ne_s t ar t _c oor di na t e s f j ] == f irst_in_set_Y) { set_Y_size++ ; line_start_coordinates [j] = pY.YO ; continue ;
}
} // else, we have passed the end of the Z-sequence i f ( s e t _ Y _ s i z e > 1 ) DBM_QuickSort_double (line_start_coordinates + first_in_set_Y_idx, set_Y_size, (long ) line_pointers + first_in_set_Y_idx) ; if (j < set_Z_end) { set_Y_size = 1 ; f irst_in_set_Y_idx = j ; f irst_in_set_Y = line_start_coordinates [j] ; line start coordinates [j ] = pY.YO ;
} " } if (i < line_count) ( set_Z_size = 1 ; first_in_set_Z_idx = i ; first_in_set_Z = line_start_coordinates [i] ; line start coordinates fi] = p.Z() ;
. } " '
} // end of the block of code for sorting the array
13 APPENDIX C
/*
********** ********** ********** ********** **********
********** ********** ********** **********
We don't need line_start_coordinates any more. Delete it. ********** ********** ********** ********** ********** ********** ********** ********** **********
*/ if (line_start_coordinates) { delete [] line_start_coordinates ; line start coordinates = NULL ;
} ~
/*
********** ********** ********** ********** **********
********** ********** ********** **********
********** ********** ********** ********** **********
********** ********** ********** **********
Main loop. Sweep the two faces.
Always keep track of open lines (lines whose startpoint we have seen, but have not yet seen an endpoint - actually, not start-and-end-points, but endpoints larger and smaller with respect to XZY ordering) .
Initially the set of open lines is empty. During every iteration we will do :
- remove all lines that were open, but should be closed now,
- check if the current line overlaps with open lines,
- add this line to the set of open lines
********** ********** ********** ********** ********** ********** ********** ********** **********
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
// these represent lists of contacts BM_LINKED_LIST_NODE facel_list, ♦face2_list ; BM_LINKED_LIST_NODE *last_facel_list, ♦last_face2 list j BM_LINKED_LIST_NODE left, right ;
BM_LINKED_LIST_NODE new_left = NULL, ♦new_right = NULL BM_LINE line_in_left, line_in_right ;
// these are the two lines we will be comparing BM_2D_B0DY *face_of_linel, face_of_line2 ; BM_LINE line_in_facel, line_in_face2 ;
14 APPENDIX C
BM_LINE line ; double k, dotp ;
BM_POINT p_open ; BM_VECTOR V ; long num_of_contacts = 0 ; long open_line_idx ; for (i = line_count - 1 ; i >= 0 ; i--) {
// initially face_of_linel is the face of the current line.
// however, later we will sort the current-sweep-line and current-open-line pointers. f a c e _ o f _ l i n e l ( ( line_pointers [i] ) - >get_loop ( ) ) - >get_2D_body ( ) ; p BM_get_greater_point_by_XZY( (line_pointers fi] ) ->get_startpt 0 , (li ne_pointers [i] ) ->get_endpt () ) ;
// compare this current line against all open lines in order to detect overlaps, ie. bendlines. for (open line_idx = i + 1 ; open_line_idx < line_count ; open__line_idx++) line = line_pointers [open_line_idx] ; if (NULL == line) {
// time-saving trick, if this is the last pointer, there is no need to try it again.
// reduce the index. if (open_line_idx == line_count - 1) { --line_count ; break ;
} continue ;
}
// ********** ********** ********** ********** **********
// check if this open line should really be removed.
// it should be removed if its endpoint is larger than p (ie. the
// startpoint of this line) .
// ********** ********** ********** **********
********** p _ o p e n
BM_get_smaller_j?oint_by_XZY (line- >get_startpt ( ) , line- >get_endpt ( ) ) if (BM_compare_points_by_XZY(p_open,p) ) { // time-saving trick.
15 APPENDIX C
// if the line we are removing from the open list is the last one, reduce the index
// instead of setting the pointer to NULL, next time we don't even try this element
// in the array, because it would be beyond the boundary if (open_line_idx == line_count - 1) { --line_count ; break ;
} line_pointers [open_line_idx] = NULL ; continue ; }
// ********** ********** ********** **********
**********
// first, check if both lines are in the same face. if yes, skip it.
// ********** ********** ********** **********
********** face_of_line2 = (line->get_loop() ) ->get_2D_body() if (face of linel == face of line2) continue ;
// ********** ********** ********** **********
**********
// Check if this line and the open line overlap. // ********** ********** ********** **********
**********
// First check if the startpoint is on the (open) line segment. if (! line->is_point_on_line (p, &k) ) continue ;
// Note that parameter k has to be in [0,1] now, because
// the line "line" is open still, ie. it startpoint is "before" p
// and endpoint is "after" p.
// Now check if vectors are parallel. v = (line->get_v() ) ( (line_pointers [i] ) ->get_ () )
/ if (v.LenO > BM_PRECISION) continue ;
// Last thing, it could be that only endpoints of the lines overlap. d o t p = ( l i n e - > g e t _ v ( ) ) % ( (line_pointers [i] ) ->get_v() ) ,- if (dotp < 0.0) { // lines are opposite
// startpoint-startpoint/endpoint-endpoint should not match i f ( ( line - >get_startpt ( ) )
16 APPENDIX C
( (line_pointers [i] ) ->get_startpt () ) | ]
( l i n e - > g e t _ e n d p t ( ) ) = =
( (line_pointers [i] ) ->get_endpt () ) ) continue ; else ( // lines have the same direction
// startpoint-endpoint/endpoint-startpoint should not match i f ( ( line - >get_endpt ( ) ) = =
( (line_pointers fi] ) ->get_startpt () ) | |
( l i n e - > g e t _s t a r t p t ( ) ) = = ( (line_pointers [i] ) ->get_endpt () ) ) continue ;
// ********** ********** ********** **********
**********
// Ok, these two lines overlap.
// First, sort lines according to which face they are in
********** ********** ********** **********
//
********** i f ( & f a c e 1 = = ( B M _ F A C E ) face_of_linel->get_3D_body() ) { line_in_facel = line_pointers fi] ; line_in_face2 = line ; p_facel = p ; p _ f a c e 2 =
BM_get_greater_point_by_XZY(line->get_startpt 0 , line->get_endpt () )
/ else { line_in_facel = line ; line_in_f ace2 = line_pointers [i] ; p _ f a c e l =
BM_get_greater_point_by_XZY(line->get_startpt 0 , line->get_endpt () )
; p_face2 = p ;
// ********** ********** ********** **********
**********
// Scan all known contacts and check if this contact should be
// added to an existing contact
// ********** ********** ********** **********
********** for (j = 0, last_face2_list = NULL num_of_contacts ; j++) { if (NULL == last_face2_list) { last_facel list = contacts ;
17 APPENDIX C
last_face2_list = last_facel_list->next ()
else { last_f acel_list = last_f ace2_list->next 0 last_face2_list = last_facel_list->next 0 ;
} left = (BM_LINKED_LIST_NODE ) last_facel_list->get_obj () ; right = ( BM_LINKED_LIST_NODE ) last_face2_list->get_obj () ; line_in_left = (BM_LINE ) lef t->get_obj ( ) ; line_in_right = (BM_LINE ) right- >get_obj ( ) ;
// Check if the line of this existing contact overlaps the new contact .
// condition is : point on the line and vectors are parallel. i f ( ! line_in_left->is_point_on_line (p_f acel, &k) ) continue ; v = ( 1 ine_i n_l e f t - >ge t _v ( ) )
(line_in_facel->get_v() ) ; if (v.Len() > BM_PRECISION) continue ;
// Check that lines in facel and face2 and exact extensions of left and right in this contact
// this is because we want every contact in the list of contacts to be a "closed" contact
// note it could be that one of the new lines in already in this contact.
// then we don't need to check. if (line_in_left != line_in_facel) { dotp = (line_in_left->get_v() ) % (line_in_facel->get_v() ) ; if (dotp < 0.0) { // lines are opposite // startpoints must match if ( (line_in_left->get_startpt 0 ) != (line_in_facel->get_startpt () ) &&
(line_in_left->get_endpt () ) != (line_in_facel->get_endpt () ) ) continue ; else ( // lines have the same direction // endpoints must match if { (line_in_left->get_endpt () ) != (line_in_facel->get_startpt () ) &&
(line_in_left->get_startpt () ) != (line_in_facel->get_endpt () ) ) continue ;
18 APPENDIX C
if (line_in_right != line_in_face2) { dotp = (line_in_right->get_v () ) % (line_in_face2->get_v() ) ; if (dotp < 0.0) { // lines are opposite // startpoints must match if ( (line_in_right->get_startpt () ) != (line_in_face2->get_startpt () ) &&
{1ine_in_right->get_endpt () ) != (line_in_face2->get_endpt () ) ) continue ; else { // lines have the same direction // endpoints must match if ( (line_in_right->get_endpt () ) != (line_in_face2->get_startpt () ) &&
(line_in_right->get_startpt 0 ) != (Iine_in_face2->get_endpt () ) ) continue ;
// everything is fine, add lines to this contact .
// note that is could be that the line is already in the contact . if (line_in_left != line_in_facel) { if (NULL ==, (new_left = new BM_LINKED_LIST_NODE (line_in_facel, ULL, left) ) ) goto failure ; last_facel_list->set_obj ( (BM_BASIC ) new_left) ; new_left = NULL ; if (line_in_right != line_in_face2) { if (NULL == (new_right = new
BM_LINKED_LIST_NODE (line_in_face2,NULL, right) ) ) goto failure ; last_face2_list->set_obj ( (BM_BASIC ) new_right) ; new right = NULL ;
} "
// now we have to break out of here, we added this contact to an existing contact. break ;
} // check if we checked all contacts and could not find a match if (j < num_of_contacts) continue ;
// ********** ********** ********** **********
19 APPENDIX C
**********
// Create a new contact.
// ********** ********** ********** **********
**********
// First, create nodes for both lines. i f ( N U L L = = ( l e f t = n e w
BM_LINKED_LIST_NODE (line_in_f acel) ) ) goto failure ; i f ( N U L L = = ( r i g h t = n e w
BM_ INKED_LIST_NODE ( line_in_f ace2 ) ) ) { delete left ; goto failure ;
} // Create lists for both sides of the contact. if (NULL == ( face2_list = new
BM_LINKED_LIST_NODE( (BM_BASIC ) right))) { delete left ; delete right ;
TOto failure ; if ?c (NULL == (facel_list = new
BM_LINKED_LIST_NODE( (BM_BASIC ) left, NULL, face2_list) ) ) { delete left ; delete right ; delete face2_list ; goto failure ;
// add the new contact to the list of contacts if (num_of_contacts < 1) contacts = facel_list ; else last_face2_list->add_after(facel_list) ;
++num of contacts ; } " "
// we use i to index line_pointers [] array. // since i will be decremented shortly, line_pointers [i] will be "implictly" put on
// the open list of sweep lines.
/*
********** ********** ********** ********** ********** ********** ********** ********** ********** free memory if necessary
********** ********** ********** ********** ********** ********** ********** ********** **********
* if (line_start_coordinates) delete f] line_start_coordinates if (line_pointers) delete [] line_pointers ;
20 APPENDIX C
// finally, create a node for the number of contacts if (NULL == (left = new BM_LINKED_LIST_NODE ( (BM_BASIC ♦) num_of_contacts,NULL,contacts) ) ) goto failure ; ♦list_of_contacts = left ; return 1 ; failure :
// free memory if necessary if (line_start_coordinates) delete f] line_start_coordinates
; if (line_pointers) delete [] line_pointers ;
Figure imgf000232_0001
if (new_left) delete new_left ; if (new_right) delete new_right ; return 0 ; }
/*
This function scans the list of contacts between two faces
(most likely created by BM_compute_all_face_to_face_contacts (...)) and removes all, but the largest contact.
Basically, it "filters" the list of contacts and removes those contacts that do not belong to the longest contact. Note that, in general, the longest contact is a list of simultaneous bendlines. Thus, the basic structure of the contact list remains the same.
For example, the first node in the list will be the number of contacts in the longest contacts.
21 APPENDIX C
This function also returns the length of the longest contact.
In this function we will be using the fact that every contact is "closed", such that in the list of lines in the contact, an endpoint of a line is equal to the startpoint of the next line.
This way the only tricky part is to compute the length of the overlapping part in the first and last line. Then we just add the length of the lines in the middle of the list.
See previous function. */ s t a t i c d o u b l e
BM_keep_largest_contact_remove_the_rest ( BM_LINKED_LI ST_NODE ♦ ♦ list of contacts )
{ " " long i , j ; if (NULL == list_of_contacts) return 0.0 ; BM_LINKED_LIST_NODE ♦contacts = list_of_contacts ; if (NULL == contacts) return 0.0 ;
// some of the most important parameters we compute in this function. double length_of_largest_contact = 0.0 ; long largest_contact_i = -1 ;
// we need to keep track of the lengths of contacts. // we need to store the length of every contact. //
// NOTICE : here we try to save some heap allocation/release time by using a pre-allocated
// array if the list of contacts is not very long.
// static double static_contact_len_array[32] ; double dynamic_contact_len_array = NULL ; double contact_len_array = NULL ;
// get the number of contacts long num_of_contacts = (long) contacts->get_obj () ; contacts = contacts->next () ;
// if no contacts, delete the entire list if (num_of_contacts < 1) {
// there is no list, delete node 0 as well. delete list_of_contacts ;
22 APPENDIX C
♦list_of_contacts = NULL ; return 0.0 ;
}
// allocate memory for the contact length array if (num_of_contacts <= 32) { contact_len_array = static_contact_len_array ; else { if (NULL == (dynamic_contact_len_array = new double [num_of_contacts] ) ) goto computation_done clean_up ; contact len array = dynamic_contact_len_array ;
} " "
// Scan all known contacts and compute the length of every contact.
// later we use these values to find the longest contact (which could be a simultaneous bendline) .
BM_LINKED_LIST_NODE last_facel_list, *last_face2_list ;
BM_LINKED_LIST_NODE line_in_list ; double k ; double first_kl, first_k2 ; double last_kl, last_k2 ; last_face2_list = NULL ; for (i = 0 ; i < num_of_contacts ; i++) { if (NULL == last_face2_list) last_facel_list = contacts
; else last_facel_list = last_face2_list->next 0 ; last_face2_list = last_facel_list->next () ;
BM_LINKED_LIST_NODE ♦left = (BM_LINKED_LIST_NODE ) last_facel_list->get_obj () ;
BM_LINKED_LIST_NODE right = (BM_LINKED_LIST_NODE ) last_face2_list->get_obj () ;
BM_LINE first_line_in_left = (BM_LINE ) left->get_obj ()
BM_LINE first_line_in_right = (BM_LINE ) right->get_obj () ;
// here is what we do. we know that the first lines in left and right have to have
// an overlapping part, we compute overlapping parameters kl and k2 with respect to the
// first line on the left, between the first lines.
// the idea is that one of the points that corresponds to these parameters (kl and k2)
// is the extreme point of the contact, we just don't know yet which one.
// then we find the last points in both lists, we know
23 APPENDIX C
that they must have non-empty
// overlapping part as well, we compute kl and k2 for these two lines as well.
// then we compate kl,k2 for the first and last pairs to find the two
// extreme points of the contact, distance between them is the length of the contact.
// compute kl and k2 for the first lines. first_line_in_left->is_point_on_line (first_line_in_right->get_sta rtpt () , &first_kl) ; first_line_in_left->is_point_on_line (first_line_in_right->get_end pt () ,&first_k2) ;
// we only want kl and k2 within the first line if (first_kl < 0.0) first_kl = 0.0 ; else if (first_kl > 1.0) first_kl = 1.0 ; if (first_k2 < 0.0) first_k2 = 0.0 ; else if (first_k2 > 1.0) first_k2 = 1.0 ;
// sort kl and k2 if (first_kl > first_k2) { k = first_kl ; first_kl = first_k2 ; first_k2 = k ; }
// find the last line in the left. for (line_in_list = left->next () ; line_in_list ; line_in_list = line_in_list->next () ) { left = line in list ;
} " "
// "left" is the last node in the left now.
BMJL.INE last_line_in_left = (BM_LINE ♦) left->get_obj ()
// find the last line in the right. for (line_in_list = right->next 0 ; line_in_list line_in_list = line_in_list->next () ) { right = line in list ;
} " "
// "right" is the last node in the left now.
BM_LINE last_line_in_right = (BM_LINE ♦) right->get_obj () ;
// compute kl and k2 for the first lines. last_line_in_left->is_point_on_line (last_line_in right->get start pt () , &last_kl) ; ~ last_line_in_left->is_point_on_line (last_line in right->get endpt () ,&last_k2) ; ~ ~
24 APPENDIX C
// we only want kl and k2 within the last line if (last_kl < 0.0) last_kl = 0.0 ; else if (last_kl > 1.0) last_kl = 1.0 ; if (last_k2 < 0.0) last_k2 = 0.0 ; else if (last_k2 > 1.0) last_k2 = 1.0 ;
// note that we have compute last kl and k2 with respect to the last line in the left.
// we really need last kl and k2 with respect to the first line in the left.
BM_POINT lastkl (last_line_in_left->get_startpt () + last_kl^ (last_line_in_left->get_v() ) ) ;
BM_POINT lastk2 (last_line_in_left->get_startpt 0 + last_k2^ (last_line_in_left->get_v() ) ) ; first_line_in_left->is_point_on_line (lastkl, &last_kl) ; first_line_in_left->is_point_on_line (lastk2, &last_k2) ;
// sort kl and k2 if (last_kl > last_k2) { k = last_kl ; last_kl = last_k2 ; last k2 = k ; }
// now we need to take the extreme points of these two pairs if (first_kl > last_kl) first cl = last_kl ; if (first_k2 < last_k2) first_k2 = last_k2 ; contact_len_array [ i] = ( f irst_k2 first kl) } (first - line - in - left->get len()) ;
// find the longest contact.
// the main feature here is to check for simultaneous bendlines last_face2_list = NULL ; for (i = 0 ; i < num_of_contacts ; i++) { if (NULL == last_f ace2_list) last_f acel_list = contacts else last_facel_list = last_face2_list->next ( ) ; last face2 list = last facel list->next() ;
// make sure we don't accept contacts that have zero length. if (contact_len_array[i] < BM_PRECISION) continue ;
BM_LINKED_LIST_NODE left = (BM_LINKED_LIST_NODE ) last_facel_list->get_obj () ;
BM_LINE first_line_in_left = (BM_LINE ) left->get_obj () ;
// check if this contact is part of a simultaneous bendline.
// if yes, add its length to the first bendline in the
25 APPENDIX C
simultaneous bendline and
// set this length here to -1.0, so that we know it later BM_LINKED_LIST_NODE ♦temp_last_facel_list,
♦temp_last_f ace2_list = NULL ; for (j = 0 ; j < i ; j++) { if (contact_len_array [i] < BM_PRECISION) continue ;
// already part of something else if (NULL == t emp_l as t_f ace2_l i s t ) temp_last_facel_list = contacts ; e l s e t e m p _ l a s t _ f a c e l _ l i s t temp_last_f ace2_list - >next ( ) ; temp_last_face2_list = temp_last_facel_list->next ()
;
BM_L I NKED_L I ST_NODE temp_lef t
(BM_LINKED_LIST_NODE ♦) temp_last_f acel_list->get_obj () ;
BM_LINE ♦temp_first_line_in_left = (BM_LINE ) temp_left->get_obj () ;
// check if the lines overlap i f ( ! first_line_in_left->is_point_on_line (temp_first_line_in_left->get _startpt () ,NULL) ) continue ; i f ( ! first_line_in_left->is_point_on_line(temp_first_line_in_left->get _endpt () ,NULL) ) continue ;
// ok, they overlap
// add the length to the first in simultaneous bend and set this to -1.0 contact_len_array[j] += contact_len_array[i] ; contact_len_array[i] = -1.0 ; break ;
» }
// in this loop we actually find the largest for (i = 0 ; i < num_of_contacts ; i++) {
// check to see if this new contact is the largest if (length_of_largest_contact < contact_len_array[i] ) { length_of_largest_contact = contact_len_array [i] ; largest contact i = i ;
) > " ' computation_done clean_up :
// remove all other contacts that are not largest BM_LINKED_LIST_NODE next_last_f acel_list ,
26 APPENDIX C
♦next_last_face2_list = NULL ;
BM_LINKED_LIST_NODE largest_contact_list_f1 = NULL, ♦largest_contact_list_f2 ; last_facel_list = contacts ; last_face2_list = last_facel_list->next () ; for (i = j = 0 ; i < num_of_contacts ; i++) { next_last_facel_list = last_face2_list->next 0 ; if (next_last_facel_list) next_last_face2_list next_last_facel_list->next () ; else next_last_face2_list = NULL ;
// make sure we don't delete the largest contact
// note : we skip two lists, facel list and face2 list if (contact_len_array fi] < 0.0 j | largest_contact_i == i) if (NULL == largest_contact_list_f1 ) largest_contact_list_f1 = last_facel__list ; e l s e largest_contact_list_f2->add_after (last_facel_list) ; largest_contact_list_f2 = last_face2_list ;
// count the number of contacts ++j ; last_facel_list = next_last_facel_list ; last_face2_list = next_last_face2_list ; continue ;
}
// ok, this is not the largest contact, delete both facel and face2 sides of the contact
BM_LINKED_LIST_NODE next_line_in_list ; for (line_in_list = (BM_LINKED_LIST_NODE ) last_facel_list->get_obj () ; line_in_list ; line_in_list = next_line_in_list) { next_line_in_list = line_in_list->next () ; delete line in list ;
} " " for (line_in_list = (BM_LINKED_LIST_NODE ♦) last_face2_list->get_obj () ; line_in_list ; line_in_list = next_line_in_list) { next_line_in_list = line_in_list->next () ; delete line in list ;
} ~ " delete last_facel_list ; delete last_face2_list ; last_facel_list = next_last_facel_list ; last_face2_list = next_last_face2_list ;
27 APPENDIX C
} // end the contact list with a NULL pointer i f ( l a r g e s t _ c o n t a c t _ l i s t _ f 2 ) largest_contact_list_f2->add_after (NULL) ;
// write the number of contacts left in node 0. also, set the correct beginning of the list.
// however, if there is no contact, erase the entire list, if (NULL == largest_contact_list_fl) {
// there is no list, delete node 0 as well. delete ♦list_of_contacts ;
♦list_of_contacts = NULL ; else {
(♦list_of_contacts) ->set_obj ( (BM_BASIC ) j) ;
(*list_of_contacts) ->add_after(largest_contact_list_f1)
7
}
// delete dynamic_contact_len_array if it was allocated if ( dynami c_c on t ac t _1 en_ar r ay ) delete [] dynamic__contact_len_array ; return length_of_largest_contact ;
/*
This function is used only by static int BM_create_bendline (...) as a subroutine. a big problem now is that we have deleted some lines. the problem is that if we have a simultaneous bend, other contacts could still be refering to these lines we just deleted. we have to go and check that, and if true, replace pointers to the lines we have changed/deleted with valid references. namely, lines that are affected are the first and last lines in the left. potentially references to them need to be replaced with references to ll and 13. */ static void check_references_in_remaining_contacts (
BM_LINKED_LIST_NODE side_l, // current list we are working with
28 APPENDIX C
BM_LINKED_LIST_NODE side_2, // list on the other side of the contact
BM_LINE ♦linel,
BM_LINE lineS, // these are old references, to be checked if still valid
BM_LINE *ll,
BM_LINE A13 // 11 and 13 are the new references
)
{
BM_LINKED_LIST_NODE sidel = side_l, side2 = side_2 ; process_next_contact :
// find the beginnings of lists in the next contact
BM_LINKED_LIST_NODE ♦contact_list ; if (NULL == (contact_list = sidel->next ()) ) return ; // done, no more lists if (NULL == (sidel = contact_list->next () ) ) return ; // done, no more lists if (NULL == (contact_list = side2->next 0 ) ) return ; // done, no more lists if (NULL == (side2 = contact_list->next () ) ) return ; // done, no more lists
// now we need to check the beginning of this contact and the end of this contact exactly the same way.
// we describe checking the beginning, check the end is the same.
// whenever we find a match, we can go to the next list (ie. don't have to continue with the
// current list) .
//
// we take first lines is sidel and side2. if the first line in sidel is either linel or line3,
// we check which of 11 and 13 overlaps the first line in side2. we know that exactly one of
// 11 and 13 has to overlap, then we replace the reference to linel/line3 with a reference to the
// one of 11/13 that overlaps the first line in side2.
BM_LINKED_LIST_NODE start_sidel = (BM_LINKED_LIST_NODE ♦) sidel->get_obj () ;
BM_LINKED_LIST_NODE start_side2 = (BM_LINKED_LIST_NODE ♦) side2->get_obj () ;
// check the beginning of the contact
BM_LINE line_in_sidel = (BM_LINE ) start_sidel->get_obj 0 ; BM_LINE line_in_side2 = (BM LINE ) start_side2->get_obj 0 ; if (line_in_sidel == linel |~| line_in_sidel == line3) {
29 APPENDIX C
if (11) { // check if 11 overlaps first line in side2 i f
(line_in_side2->is_point_on_line_segment (ll->get_startpt 0 , NULL)
I I I I line_in_side2->is_point_on_line_segment (ll->get_endpt () , NULL)) { start_sidel->set_obj (ll) ; goto process next contact ;
} if (13) { // check if 13 overlaps first line in side2 i f
(line in_side2->is_point_on_line_segment (13->get_startpt () , NULL)
I I I I line_in_side2->is_point_on_line_segment (13->get_endpt () , NULL) ) start sidel->set robj (13) ; goto process next contact ; }
BM_LINKED_LIST_NODE line_in_list, prev_line_in_list ;
// find the last line in side2. for (line_in_list = start_side2->next () ; line_in_list line_in_list = line_in_list->next () ) { p}rev-line_in_list = line in list ;
// "prev_line_in_list" is the last node in the left now. Iine_in_side2 = (BM_LINE ) prev_line_in_list->get_obj () ; // find the last line in sidel. for (line_in_list = start_sidel->next () ; line_in_list ; line_in_list = line_in_list->next () ) { prev_line_in_list = line_in_list ;
// "prev_line_in_list" is the last node in sidel now. line_in_sidel = (BM_LINE ) prev_line_in_list->get_obj () ;
// check the end of the contact if (line_in_sidel == linel | | line_in_sidel == line3) { if (11) { // check if ll overlaps first line in side2 i f
(line_in_side2->is_point_on_line_segment (ll->get_startpt () , NULL) i I line_in_side2->is_point_on_line_segment (ll->get_endpt () , NULL) ) { prev_line_in_list->set_obj (ll) ; goto process_next_contact ;
30 APPENDIX C
if (13) { // check if 13 overlaps first line in side2 i f
(line_in_side2->is_point_on_line_segment (13->get_startpt () , NULL)
II line_in_side2->is_point_on_line_segmen (l3->get_endpt () , NULL) ) prev_line_in_list->set_obj (13) ;
} goto process_next_cont ct ;
}
/*
This function will create a simple (regular) bendline between the two faces, based on the contact list given as input. Once done, it will erase the contact list.
In this function we assume that edges of faces are sorted according to the left-hand side rule.
This function returns TRUE iff everything is fine.
NB! the key here is not to invalidate anything in the part as we create a new bendline.
In order to accomplish that, we will create the bend op is isolation (without the bendline) , and then later attach it to the bendline.
Also, we will create topology only after the bendline is built and added to the part.
Note that this function creates bendline information that is consistent with facel (mainly, facel normal) .
However, face2 normal can be inconsistent with this information, but that has to be fixed later. */ static int BM_create_bendline (BM_PART & part, BM_LINKED_LIST_NODE ♦♦contact, BM BENDLINE ♦♦bendline created /♦ OUT /)
{
// so far, nothing is created bendline_created = NULL ;
// it is possible, that we are building bendlines for the flat version of the part.
// if this variables is TRUE, we are building bendlines for the 3D-version, otherwise for the flat. int using_3D_version = 1 ;
31 APPENDIX C
// later we need to create a bendline centerline
// these are the start-end points of the bendline centerline
// note that they are points pi and p2 on the facel side of the bendline
// this is done because sometimes (when the bendline is not bent) we use the
// facel surface as the bendline surface, ie. the bendline orientation is defined
// with respect to facel
BM_POINT bendline_centerline_pl, bendline_centerline_p2 ;
// contact list parameters
BM_LINKED_LIST_NODE *line_in_list, next_line_in_list ; BM_LINKED_LIST_NODE left, right ; int number_of_lists = (long) (contact) ->get_obj () ; BM_LINKED_LIST_NODE contact_list = (contact) ->next () ; left = (BM_LINKED_LIST_NODE ) contact_list->get_obj () ; r i g h t = ( B M _ L I N K E D _ L I S T _ N O D E ) (contact_list->next () ) ->get_obj () ;
BM_LINE first_line_in_left = (BM_LINE ) left->get_obj () ; BM_LINE ♦first_line_in_right = (BM_LINE ) right->get_obj () ; BM_LINE last_line_in_left ; BM_LINE left_line, right^ine ;
// get loops in both bodies
BM_LOOP facel_loop = first_line_in_left->get_loop () ; BM_LOOP face2_loop = first_line_in_right->get_loop () ; if (NULL == facel_loop | | NULL == face2_loop) return 0 ;
// 2D-bodies of either face
BM_2D_BODY facel_body = facel_loop->get_2D_body() ;
BM_2D_BODY face2_body = face2_loop->get_2D_body() ; if (NULL == facel_body j j NULL == face2_body) return 0 ;
// get facel and face2
BM_FACE facel = (BM_FACE ) facel__body->get_3D_body() ;
BM_FACE face2 = (BM_FACE ) face2_body->get_3D_body() ; if (NULL == facel j | NULL == face2) return 0 ;
// check whether we are using the flat version of the part, or 3D-version of the part. if (facel->get_current_3D_ ersion() ! = facel_body | ] face2->get_current_3D_version() != face2_body) using_3D_version = 0 ;
// get surfaces of either faces
BM_PLANE facel_plane, face2_plane ; facel_plane = (BM_PLANE ) facel_body->get_surface () ; face2_plane = (BM_PLANE ) face2_body->get_surface () '•
32 APPENDIX C
/*
First we will do everything that has to do with the bendline - create a bendline, create a bend op, set bend op parameters, create and set cylinder for the bendline, set bendline centerline, etc. */
// try to figure out whether we have a FRONT or BACK bend.
B M _ V E C T 0 R v_face2_body( (face2_plane->get_normal () ) (first_line_in_right->ge t_v())) ; // this vector
// points toward? the inside of face2 on the plane of face2
B M _ V E C T 0 R v_face2_normal (v_face2_body^ (first_line_in_left->get_v() ) ) ; // this is the correct normal for face2 ?
// compute the angle between faces double angle = v_face2_normal Λ (facel_plane->get_normal () ) ;
// compute bend type (FRONT/BACK) if (fabs (angle) <= BM_ANGLE_TOLERANCE) angle = PI ; else {
BM_VECT0R v( (facel_plane->get_normal () ) +v_face2_normal) if (v % (first_line_in__left->get_v() ) > 0.0) angle = PI + angle ; // BACK bend else angle = PI - angle ; // FRONT bend }
// create a new empty bendline and add it to the part BM_2D_BODY ♦new_auto_bendline = new BM_2D_B0DY ; if (NULL == new_auto_bendline) return 0 ; BM_BENDLINE new aendline = new BM_BENDLINE (&part, using_3D_version ? NULL : new_auto_bendline, using_3D_version ? new_auto_bendline : NULL) ; if (NULL == new_bendline) { delete new_auto_bendline ; return 0 ;
}
// create a regular bend op for the bendline
B M_B END_0 P_R E GUL AR new_bend_op = new
BM_BEND_OP_REGULAR (NULL, angle, 0.0 ,0.0) ; // don't attach to bendline yet if (NULL == new_bend_op) ( delete new_bendline ; return 0 ;
} // attach this bend op to the bendline. this will just assign
33 APPENDIX C
the bend_op variable in the bendline new_bendline->attach_bend_op (new_bend_op) ;
// create bendline surface, if angle is not 180 degrees, we create a cylinder, otherwise a (facel) plane. BM_SURFACE bend_surface ; if (fabs (angle - PI) <= BM_ANGLE_TOLERANCE) { // bendline not being bent
// note : facel plane is the bendline surface bend_surface = new BM_PLANE (facel_plane) ; new_bendline->Do_This_Bend(0) ; // this will invalidate 3D version as well, later we validate it.
// set sense to the same as facel sense new_auto_bendline->set_sense (facel_body->get_sense () ) ; else {
// first, compute vx
B M _ V E C T 0 R v_facel_body ( (facel_plane->get_normal () ) (f irst_line_in_lef t->get _v ( ) ) ) ;
// v_facel_body points towards the inside of facel on the plane of facel v_facel_body.set_length(-l .0) ; // invert and normalize v_face2_body.set_length (-1.0) ; // invert and normalize
// this is the vx vector of the bendline surface BM_VECTOR vx(v_facel_body + v_face2_body) ; b e n d _ s u r f a c e = n e w
BM_CYLINDER (f irst_line_in_lef t->get_startpt ( ) , f irst_line_in_lef t->get_endpt () , vx, 0.0) ; new_bendline->Do_This_Bend(l) ; // this will invalidate 3D version as well, later we validate it.
// set sense to 0, because we want the bendline (cylinder) to represent explicitly OUTSIDE
// ie. thickness vector is opposite to the normal (= radius vector) . new_auto_bendline->set_sense (0) ; if (NULL == bend_surface) { delete new_bendline ; return 0 ;
} new_auto_bendline->set_surface (bend_surface) ;
// lastly we need to create the bendline centerline, but for that we need to know its length, and
34 APPENDIX C
// start-end-points. However, for that we need to process the contact list which contains the
// lines that are adjacent. We will do that next, and when done, will create bendline centerline.
/*
Second, we will break some lines, if necessary, and combine all adjacent lines into a one adjacent line. We will also create adjacency information between facel-bendline and face2-bendline.
*/
// notice that processing one side of the contact is independent of the other side.
// moreover, the logic is exactly the same, therefore, we will use the following code
// to process both facel' side and face2' side. char face2_processed = 0 ; process_one_side_of_the_contact :
// in general, the contact line (on the side of either face (facel and face2) ) will consist
// of three lines - we have a list of lines, first line is the line before the contact, the
// second line is the contact line, the last line is the line after the contact.
// these variables will be used to compute these three lines. double k ; double kO, kl, k2, k3 ; // parameters k for the first line in the left double end_kl, end_k2 ; // parameters k for the last line in the left list
BM_POINT pO, pi, p2, p3 ; // pO - p3 are the endpoints of the edges that will be left (ie. endpoint of left_line, 12, 13) .
// pO and p3 and the two extreme endpoints and trivial to find, we really need to compute only pi and p2.
BM_LINE *11, +12, *13 ; // ll is the line before 12, 12 is the line that is adjacent, 13 is the one after it.
// process first line of the left side kO = 0.0 ; k3 = 1.0 ; first_line_in_left->is_point_on_line (first_line_in_right->get sta rtpt () , &kl) ; first__line_in_left->is_point_on_line (first_line_in_right->get end pt () , &k2) ; if (kl > 1.0) kl = 1.0 ;
35 APPENDIX C
else if (kl < 0.0) kl = 0.0 ; if (k2 > 1.0) k2 = 1.0 ; else if (k2 < 0.0) k2 = 0.0 ; if (k2 < kl) { k = kl ; kl = k2 ; k2 = k ; }
// note that we cannot yet compute pO, pi and p3 because we don't know the relative order
// of the first and last lines in the left list
// find and process the last line for (line_in_list = left ; line_in_list ; line_in_list = next_line_in_list) { if (NULL == (next_line_in_list = line_in_list->next () ) ) left_line = (BM_LINE ) line_in_list->get_obj () ;
// first, we have to find the end of the face2 list for (line_in_list = right ; line_in_list ; line_in_list = next_line_in_list) { if (NULL == (next_line_in_list line in list->next () ) ) break ;
" ~ right_}line = (BM_LINE ) line_in_list->get_obj () ; left_line->is_point_on_line (right_line->get_startpt () , &end_kl) ; left_line->is_point_on_line (right_line->get_endpt () ,&end_k2) ; if (end_kl > 1.0) end_kl = 1.0 ; else if (end_kl < 0.0) end_kl = 0.0 ; if (end_k2 > 1.0) end_k2 = 1.0 ; else if (end_k2 < 0.0) end_k2 = 0.0 ; if (end_k2 < end_kl) { k = end_kl ; end_kl = end_k2 ; end_k2 = k ; } break ;
// now we have to compute points pO, pi, p2 and p3. // but first we need to convert end-k parameters to equivalent parameters with respect to the // first line in the left pO = left_line->get_startpt () ; pi = left_line->get_startpt () + end_kl (left_line->get_v() )
7 p2 = left_line->get_startpt () + end_k2 (left_line->get_v() ) p3 = left_line->get_endpt () ;
// check kO first_line_in_left->is_point_on line(p0,&k) ; if (k < kO) kO = k ;
36 APPENDIX C
// check kl first_line_in_left->is_point_on__line (pi, &k) ; if (k < kl) kl = k ;
// check k2 first_line_in_left->is_point_on_line (p2, &k) ; if (k > k2) k2 = k ,-
// check k3 first_line_in_left->is_point_on_line (p3 , &k) ; if (k > k3) k3 = k ;
// here we can compute pO, pi and p3. later we compute p2. pO = first_line_in_left->get_startpt () + kO (first_line_in_left->get_v() ) ; pi = first_line_in_left->get_startpt () + kl (first_line_in_left->get_v{) ) ; p2 = first_line_in__left->get_startpt () + k2 (first_line_in_left->get_v() ) ; p3 = first_line_in_left->get_startpt () + k3 (first__line_in_left->get_v() ) ;
// ok, we have computed p0-p3. now we will erase left list, except for the first line.
// we need the first line later.
// actually, the first line will, in the future, point to new line 12.
BM_LOOP ♦left_loop = first_line_in_left->get_loop () ; last_line_in_left = NULL ; // the last line in the left, we need it later to replace out-of-date pointers with valid ones. line_in_list = left->next() ; // this is the second line in the left list. left->add_after(NULL) ;
// note : we will erase all lines in the left list, starting from the second line. for (; line_in__list ; line_in_list = next_line_in_list) { next_line_in_list = line_in_list->next () ; // store a pointer to the last line last_line_in_left = (BM_LINE ) line_in_list->get_obj ()
; left_loop->remove_edge (last__line_in_left) ; delete last_line_in_left ; delete line in list ;
} " ~
// finally, create the adjacent line 12, and two more lines (11 and 13) if necessary, if (pO != pi) {
11 = first_line_in_left ; ll->set (p0,pl) ;
12 = new BM_LINE(pl,p2) ;
37 APPENDIX C
left_loop->add_edge_after (ll, 12) ; else (
11 = NULL ;
12 = first_line_in_left ; 12->set (p0,p2) ;
} if (p2 != p3) (
13 = new BMJLINE (p2,p3) ; left loop->add_edge_after(12, 13) ;
} else 13 = NULL ;
// last thing, create topology by making this line adjacent to the bendline
12->make_body_adjacent (new_bendline) ;
// a big problem now is that we have deleted some lines .
// the problem is that if we have a simultaneous bend, other contacts could still be refering
// to these lines we just deleted.
// we have to go and check that, and if true, replace pointers to the lines we have changed/deleted
// with valid references.
//
// namely, lines that are affected are the first and last lines in the left.
// potentially references to them need to be replaced with references to 11 and 13. if (11 j j 13) check_references_in_remaining_contacts ( face2_processed ? contact_list->next () : contact_list, // current list we are working with face2_processed ? contact_list : contact_list->next () , // list on the other side of the contact first_line_in_left, last_line_in_left, // these are old references, to be checked if still valid ll, 13 // ll and 13 are the new references ) ;
// we will use the same piece of code to process both sides of the contact .
// if face2 side has not been processed, do it now.
// however, first we need to set some values of variables that are commonly used. if ( ! face2_processed) { face2_processed = 1 ;
// first, 12 should be the left line.
// 12 is the real adjacent line (on the left) . now it
38 APPENDIX C
becomes the right line. left->set_obj (12)
// now we need to switch left and right sides // switch lines first_line_in_left = first_line_in_right ; first_line_in_right = 12 ;
// switch lists line_in__list = left ; left = right ; right = line_in_list ;
// store bendline centerline start-end points bendline_centerline_pl = pi ; bendline_centerline_p2 = p2 ; goto process one side_of the_contact ; }
We can delete contact lists now.
BM_LINKED_LIST_NODE list, next_list ; int lists_deleted = 0 ; // note, we can only delete first two lists for (list = contact_list ; lists_deleted < 2 && list ; list = next_list) { next_list = list->next() ;
// delete the list for (line_in_list = (BM_LINKED_LIST_NODE ) list->get_obj () ; line_in_list ; line_in_list = next_line_in_list) { next_line_in_list = line_in_list->next 0 ; delete line in list ;
} " " delete list ;
++lists deleted ;
} // set the correct number of contacts left and update the pointers long num_contacts = (long) (contact) ->get_obj () ; if (--num_contacts < 1) {
// if no contacts left, erase the whole contacts list delete contact ;
contact = NULL ;
}
39 APPENDIX C
else {
(♦contact) ->set_obj ( (BM_BASIC ) num_contacts) ;
(♦contact) ->add after(list) ;
}
*
Finally, create centerline. Make sure direction and length are correct.
Note, pi and p2 are defined with respect to facel.
Ie. pi -> p2 is the direction on the contact on the side of facel .
*/
B M _ L I N E centerline (bendline_centerline_pl,bendline_centerline_p2) ; if (fabs (angle - PI) <= BM_ANGLE_TOLERANCE) { // bendline not being bent
// facel plane is the bendline surface i f ( f a ce l - >ge t_idx ( ) > f ac e 2 - >ge t_id ( ) ) centerline . reverse_line ( ) ; else if (angle < PI ) { i f ( f ac e l - >ge t_i dx ( ) < f ace 2 - >get_i dx ( ) ) centerline . reverse line ( ) ; else angle is > PI
Figure imgf000251_0001
(facel - >get_idx ( ) > face2 - >get_idx ( ) ) centerline.reverse lineO ;
} new_auto_bendline->set_center_line(centerline) ;
// if we are building bendlines for the 3D-version of the part,
// make sure 3D-version of the bendline is validated because most likely we
// want to UNFOLD right away. if (using_3Diversion) new_bendline->validate_3D_version() ;
bendline_created = new_bendline ; return 1 ;
}
/*
The purpose of this function is to create a minimum number of bendlines so that a part that has disconnected components consisting of faces, the part will be connected once we add these new bendlines.
40 APPENDIX C
This function assumes that the part has thickness 0.
The basic idea we use in this function is maximum spanning tree.
We model the part by an undirected graph, where faces are the nodes of the graph and there is an edge between two nodes iff these two faces are in contact (ie. are touching each other) , the cost (or length) of the edge is the length of the longest contact between these two faces
(ie. the length of the longest possible bendline between the two faces) .
In order to create bendlines we compute a maximum spanning tree for this graph and create a bendline for every edge of the graph that is in the maximum spanning tree.
There are two problems however :
It could be that the part already contains some bendlines (ie. some faces are already connected) .
- When we compute the maximum spanning tree, we can have two fringe-edges that have the same length. In that case, we don't want to break ties randomly, but instead choose an edge that would minimize the diameter of the spanning tree (the maximum distance between any two vertices of the tree) .
Algorithm :
We will process faces one-by-one, starting from the first faces of the part and proceeding until the last faces, and building the maximum spanning tree along the way as we go.
For every pair of faces, such that at least one of the is not yet in the spanning tree, we keep the longest contact between them. When we expand the spanning tree, we choose the contact between a face in the tree and a face not in the tree that is the longest contact between any face in the tree and a face outside. If there is a tie, we choose an edge that would minimize the */
/*
41 APPENDIX C
Given a face (facel) this structure contains information about the contact between this face and another face.
For any two faces, we need to know if there is a contact between these two faces and if yes, what is its length. The simplest way to handle this data is to store it as a two-dimensional array. However, this would take a lot of space, most of which would be wasted, usually, since if there are many faces, most of them do not have any contacts between them.
Instead we will store this info for every face as a list of structures. We will create this record (ie. structure) only if the length of the contact between two faces is greater than 0. */ typedef struct CONTACT_INFO {
// here we will keep track what is the length of the longest contact between any two faces
// this is really a two-dimensional array double length ;
// here we keep a pointer to the other face BM_FACE face2 ;
// here we will keep the longest contact for any two faces // this is really a two-dimensional array stored as a linked list of lists .
BM_LINKED_LIST_NODE contact ;
// a pointer to the next structure in a list CONTACT_INFO next ;
} contact_info ;
/*
This is a very basic function used by many functions in this file, It deletes a contact list.
*/ static void delete_contact_info_list (contact_info ♦list) contact_info c, c αext ;
42 APPENDIX C
BM_LINKED_LIST_NODE clist, next_clist ; BM_LINKED_LIST_NODE line_in_list, next_line_in_list ; for (c = list ; c ; c = c_next) { c_next = c->next ; if (c->contact) {
// skip the header = num of contacts for (clist = (c->contact) ->next () ; clist ; clist = next_clist) { next_clist = clist->next () ;
// delete the list for (line_in_list = (BM_LINKED_LIST_NODE ) clist->get_obj () ; line_in_list ; line_in_list = next_line_in_list)
{ next_line_in_list = line_in_list->next () delete line in list ;
} " " delete clist ;
} // delete the header delete c->contact ;
} delete c ; }
static void delete_contact_info_structure (contact_info *c)
{
BM_LINKED_LIST_NODE clist, next_clist ;
BM_LINKED_LIST_NODE line_in_list, next_line_in_list ; if (NULL == c) return ; if (c->contact) {
// skip the header for (clist = (c->contact) ->next () ; clist ; clist = next_clist) { next_clist = clist->next () ;
// delete the list for (line_in_list = (BM_LINKED_LIST_NODE ) clist->get obj () ; line_in list ; line in list = next line in list)
{ next_line_in_list = line_in_list->next () ;
43 APPENDIX C
delete line_in_list ;
} delete clist ;
} // delete the header delete c->contact ;
} delete c
/*
This function will compute and store the best (ie. longest) contact between two faces . */ static int compute_the_longest_contact_between_faces ( BM_FACE & facel / IN /, BM_FACE & face2 / IN /, contact__info ♦♦computed_contact_list / OUT /)
// so far we have computed nothing ♦computed_contact_list = NULL ;
BM_LINKED_LIST_NODE ♦contact_list ; // a list of all contacts between facel and face2 we will compute if (! BM_compute_all_face_to_face_contacts (facel, face2, &contact_list) ) return 0 ; d o u b 1 e x = BM_keep_largest_contact_remove_the_rest (&contact_list) ; if (x < BM_PRECISION) return 1 ; // no contact between these two faces contact_info +c ; if (NULL == (c = new contact_info) ) { // delete contact list
Figure imgf000255_0001
// delete the list for (line_in_list = (BM_LINKED_LIST_NODE ♦) clist->get_obj () ; line_in_list ; line_in_list = next_line_in_list) next_line_in_list = line_in_list->next () ; 44 APPENDIX C
delete line in list
} " " delete clist ;
} delete contact_list ; return 0 ; }
// initialize the structure c->contact = contact^list ; c->next = NULL ; c->face2 = &face2 ; c->length = x ; ♦computed_contact_list = c ; return 1 ;
/*
This function adds a new face to the current connected component .
It also computes the longest contacts between this new face, and all other faces that have not been processed. */ static int add_face_to_connected_component (BM_PART part,
BM_FACE ♦face2 / this is the face we are adding to the connected component /, long ♦end_id / an index of the last face in the connected component, this is where face2 is. /, contact_info ♦♦all_contacts / all contact info between face2 and other outside faces will be here /
/ we will compute it and construct this list in this function /,
BM_FACE ♦♦idx_to_face_mapping)
BM_FACE current_face ; contact_info last slist = NULL, +cl ;
// just in case face2 has no adjacent faces outside the connected component all_contacts [end_id] = NULL ;
// in this loop we want to compute all contacts between face2 and all other
// faces not yet in any connected component.
45 APPENDIX C
for (current_face = part->get_face_list () ; current_face ; current_face = (BM_FACE ) current_face->next () ) { if (current_face->get_user_id () >= 0) continue ; // current_face is in some other connected component
// compute the best contact between face2 and current_face if (! compute_the_longest_contact_between_faces (+face2, ♦current_face, &cl) ) return 0 ; if (NULL == cl) continue ; // there is no contact between these two faces if (NULL == last_clist) all_contacts [end_id] = cl ; else last_clist->next = cl ; last clist = cl ;
} ~ face2->set_user_id(^end_id) ; idx_to_face_mapping [end_id] = face2 ; ++(^end_id) ; return 1 ;
/*
These two functions allow the user to set and get the distance between two faces in the topology graph. dist_btw_faces is a upper right half of a two dimensional array. */ static long get_face2face_dist (unsigned char dist_btw_faces, long number_of_faces, long dist_array_size, long j, long i) long k ;
// distance between face_i and face_i is zero if (i == j) return 0 ;
// sort indeces if (j < i) { k = i ; i = j ; j = k ; } k = number_of_faces - i ; return dist_btw_faces [dist_array size - ((k k-1)) >> 1) + (i - i) - 1] ; } static void set_face2face_dist (unsigned char ♦dist_btw_faces,
46 APPENDIX C
long number_of_faces, long dist_array_size, long j, long i, unsigned char distance)
{ long k ;
// distance between face_i and face_i cannot be set if (i == j) return ;
// sort indeces if (j < i) { k = i ; i = j ; j = k ; } k = number_of_faces - i ; dist_btw_faces [dist_array_size - ((k*(k-D) >> 1) + (j - i) - 1] = distance ; }
/*
This function returns the largest distance between the given face and other faces in the connected component.
*/ static long get_largest_distance_for_face (unsigned char ♦dist_btw_faces, long number_of_faces, long dist_array_size, long start_id, long end id, long face id)
{ long j , k ; if (NULL == dist_btw_f aces) return 0 ; long current_f ace_to_f ace_distance = 0 ; for (j = start_id ; j < end__id ; j + + ) { k get_f ace2f ace_dist (dist_btw_faces , number_of_faces , dist_array_size , j , f ace_id) ; i f ( k > c u r r e n t _ f a c e__t o_ f a c e_d i s t an c e ) current face to face distance = k ;
" } " ~ " return current_f ace_to_f ace_distance ;
/*
This is the main AutoBend function. Its purpose is to automatically create bendlines for the part. */
47 APPENDIX C
int BM_PART: :auto_bend(void)
{ long i, j , k ;
BM_FACE ♦current_face ;
BM_FORMING current_forming ;
BM_BENDLINE ♦current_bendline ;
// at end of the function we release memory, this code for releasing memory is shared
// between the cases when this function fails, or succeeds.
// therefore, before we get to that code, we have to know the return code. int ret_value ;
// these are the two faces we will be creating a bendline for (ie. between these two faces) . BM_FACE facel, face2 ;
// here we keep a list of information about contacts between every face and other faces.
// this is an array lists. contact_info ♦♦all_contacts = NULL ;
// here we will keep track what face corresponds to each row in face_to_face_length[] and all_contacts [] arrays BM_FACE ♦♦idx_to_face_mapping = NULL ;
// this (two-dimensional) array is used to store distances between faces in the TOPOLOGY GRAPH.
// these distance values are used to break ties in the maximum spanning tree algorithm when
// two edges have the same length. Note that the distance between (i,j) is the same as
// the distance between (j,i) . This means that the distance matrix is a symmetric matrix, and we
// only need to store one half (upper right triangle) to save space.
// we will use this method of breaking ties only when the number of faces is less than 256.
// this has two advantages : 1) the distance between any two faces is always less than 256,
// and therefore we only need a char (8 bits) to store the distance values, 2) since we only
// need a char for a pair, the total this array can take is 32K bytes, which is not too much memory. unsigned char dist_btw_faces = NULL ,•
// this will be the size of the distance array, given some number of faces long dist_array_size ;
48 APPENDIX C
// we will have to create a heap because some portion of the part can already be connected
// and we need to make sure we don't create any bendlines for that portion of the part.
// we will use a heap to traverse that portion of the part. long body_priority = number_of_formings + number_of_faces + number_of_bendlines ;
// Check if there are any bodies. If no, we are done. if (body_priority < 1) return 1 ;
// this is the heap we will allocate, this is used when we add a face to the connected component
// to add all other faces connected to it as well, the problem is that the part could already
// contain some bendlines.
DBM_HEAP heap = NULL ;
// this is the start-index (in face_to_face_length[] and all_contacts [] ) arrays
// of the current connected component long start_id = 0 ;
// this is the end-index (in face_to_face_length[] and all_contacts [] ) arrays
// of the current connected component long end_id = 0 ;
// if TRUE, we are starting a new connected component int starting_new_connected_component = 1 ;
// allocate memory for local variables i f ( NULL = = ( a l l _ c o n t a c t s = n e w contact_inf o* [number_of_f aces] ) ) goto failure ; if (NULL == ( idx_t o_f ace_mapp ing = new
BM_FACE* [number_of_faces] ) ) goto failure ; if (NULL == (heap = new DBM_HEAP (0 , NULL, NULL, body_priority) ) ) goto failure ; if (number_of_f aces < 256) { // allocate memory for the face -face distance array only when
// the number of faces is not too large dist_array_size = (number_of_f aces* (number_of_f aces - 1) ) >> 1 ; if (NULL == (dist_btw_faces = new unsigned charfdist array size])) goto failure ;
"} ++body_priority ; // just in case, we don't want the priority to go to 0 later.
// initialize arrays for (i = 0 ; i < number__of_f aces ; i+ + ) { all_contacts [i] = NULL ;
49 APPENDIX C
idx to face mapping[i] = NULL ;
} " " "
// initially mark all faces as not processed for (i = 0, current_face = first_face ; current_face ; current_face = (BM_FACE ♦) current_face->next () ) { current_face->this_body_already_processed = 0 ;
// this will tell us whether this face has been already processed.
// if yes, this id is the index in face_to_face_length[] and all_contacts f] arrays. current face->set_user_id(-1) ;
}
/*
First, try to expand the maximum spanning tree of the current connected component of faces.
*/
// these two variables are used in tie-breaking long best_face_to_face_distance, current_face_to_face_distance
// this is the length of the best contact so far (ie. the longest contact) double best_length ;
// this is a pointer to the best contact_info structure found so far contact_info best_cntct ; expand_spanning_tree :
// first, check if all faces have been processed // end_id is where we will put the next face we add to the connected component if (end_id >= number_of_faces) goto done ; contact_info cntct, cntct_next, ♦cntct_prev ; best_length = -1.0 ; best_face_to_face_distance = 999999 ; // a really large number
// in this loop we check all faces already in the connected component and try
// to find a face that has the largest contact between itself and an adjacent face outside the
// current connected component . for (i = start_id ; i < end_id ; i++) (
// in this loop we are checking for a largest contact between the current face
// in the connected component and all of its adjacent faces outside the connected component.
50 APPENDIX C
cntct_prev = NULL ; for (cntct = all_contacts [i] ; cntct ; cntct = cntct_next) { cntct_next = cntct->next ;
// check if this adjacent face is already processed if ( (cntct->face2) ->get_user_id() >= 0) (
// this means that face2 has already been added to the connected component
// and we don't really need the contact info stored in this structure any more.
// we will delete it.
// this will some time in the future and free up some space. delete_contact_info_structure (cntct) ; if (NULL == cntct_prev) all_contacts [i] = cntct next else cntct_prev->next = cntct_next ; continue ;
}
// ok, this adjacent face not processed.
// check if it is better than the previously known best.
// first check if there is a tie, and if we have allocated a face-face distance array
// then use the face-to-face distances to break the tie if (fabs (cntct->length - best_length) <= distance_tolerance && dist_btw_faces) {
// if tie-breaking is used, compute the largest distance for this face (ie. facel) c u r re n t _ f a c e__t o_ f a c e_d i s t an c e get_largest_distance_for_face (dist_btw_faces, number_of_faces , dist_array_size , start_id, end_id, i) ,-
// prefer the one with the smaller largest distance if (current_face_to_face_distance < best_face_to_face_distance) { facel = idx_to_face_mapping[i] ; face2 = cntct->face2 ; best_length = cntct->length ; best_cntct = cntct ; be s t_f a c e_t o_ f a c e_d i s t anc e current face to face distance ;
Figure imgf000262_0001
51 APPENDIX C
// take simply the one that is better else if (cntct->length > best_length) { facel = idx_to_face_mappingti] ; face2 = cntct->face2 ; best_length = cntct->length ; best_cntct = cntct ;
// if tie-breaking is used, compute the largest distance for this face (ie. facel) best_face_to_face_distance = current_f ac e__t o_f ac e_d i s t anc e get_largest_distance_f or_f ace (dist_btw_f aces , number_of_f aces , di st_array_s i z e , start id, end id, i ) ;
} cntct prev = cntct ;
) } "
// at the end of this loop,
// facel, face2, best_cntct should have correct values, if best_length > 0.0,
// that means we can expand the tree.
/*
Check if we can expand the spanning tree.
Note, for this point on until we get back to expanding the connected component, we will be using only face2, ie. we won't be needing facel.
The only case is when we create a new bendline, but we can extract face id's from the contact list.
*/ if (best_length < distance_tolerance) (
// looks like we cannot expand the spanning tree
// none of the faces in the current connected component has any adjacent faces
// outside the connected component.
// most likely this connected component is finished and, since there must be still faces left,
// there is more than one connected component .
//
// next we try to find the first face in the next connected component so that we
// can continue and create all bendlines for this new conencted component. for (current_face = first_face ; current_face current_face = (BM_FACE ) current_face->next () ) {
52 APPENDIX C
if (current face->get user id() < 0) break ;
} if (NULL == current_face) goto done ; // we should never get here
// first, we can delete all contact information about the current (now old) connected component for (i = start_id ; i < end_id ; i++) { delete_contact_info_list (all_contacts [i] ) ; all contacts fi] = NULL ;
} "
// here we will be starting a new connected component starting_new_connected_component = 1 ; start__id = end_id ;
// we will skip the bendline creation normally needed when adding a face to a connected component face2 = current_face ; else {
// ok, we are in the middle of a conencted component starting_new_connected_component = 0 ;
// create a bendline between facel and face2 // notice : we might have to create a simultaneous bend l o n g n u m _ c o n t a c t s = ( l o n g )
(best_cntct->contact) ->get_obj () ;
BM_BEND_PROPERTY_SIMULTANEOUS sim_bend = NULL ; if (num_contacts > 1) { sim_bend = new BM_BEND_PROPERTY_SIMULTANEOUS (this, num_contacts, NULL) ; if (NULL == si bend) goto failure ;
} BM_BENDLINE new_bendline ; for (long contact s_done = 0 ; contacts_done < num_contacts ; contacts_done++) { i f ( ! BM_create_bendline ( * t i s ,
& (best_cntct->contact) , &new_bendline) ) goto failure ;
// note that this function will delete one contact for which a bendline was created as well if (num_contacts > 1) {
// add this bendline to the simultaneous property new_bendl ine - >add_property (sim_bend) ;
53 APPENDIX C
// store "1 + the current index of the last connected-component-face" j = end_id ;
// we could add face2 to the connected component right away, but we could save some time by
// first checking if face2 has any other stuff (outside this connected component) connected to it.
// if yes, we will be adding that stuff to this connected component right away,
// but in that case there is no need for us to compute contacts between face2 and that other
// stuff in the first place.
// Therefore, we will just remember that face2 should be added, will process adjacent stuff first,
// and then will actually add face2 (and some more stuff may-be) to the connected component.
//
// Note : we will actully put face2 in the heap, and when we remove it from the heap,
// we will remember to add it to the connected component
/*
Now we need to check if this face (ie. face2) has any other 3D-bodies connected to it.
It yes, then we need to pursue these connections in order to add all faces connected to face2 to the current connected component.
*/ heap->empty() ; if (! heap->insert (body_priority--, (long) face2) ) goto failure ; face2->this_body_already_processed = 1 ;
// check if face2 has a parent face or not. if not, set the id in local array equal to
// face2's own id. this way we know it has no parent face.
//
// IMPORTANT : normally user_id of every face is a pointer to its index in the contact-info array.
// temporarily we will use this information to keep track which of the faces already processed
// is the parent-face (in the topology graph) of every new face added to the connected component .
// this information will be used later to compute distances in the face topology graph.
// the following loop (controlled by the heap) stores all faces not yet in the connected
// component, but connected to this face2.
// later when the actualy adding of new faces to the conencted
54 APPENDIX C
component is done,
// we overwrite user_id with the correct value. if ( ! starting_new_connected__component) f ace2->set_user_id (facel->get_user_id {) ) ; else face2->set_user_id(end_id) ;
// in the following while loop we will use this_body_already_processed member variable to keep
// track whether a varible is processed; not processed, but sitting in the heap; or unseen yet.
// 0 - unseen body
// I - body in the heap
// 2 - body already finished
// also, in this while loop we will be using the user_defined_id of every 3D-body to keep
// track of the parent face of every 3D-body we traverse.
// this has two benefits : 1) we will remember the parent face of every face and can compute
// distances between faces later, and
// 2) this way when faces are later added to the spanning tree, distance between some other
// face and this face will not be computed, since it is not necessary.
BM_3D_B0DY body ; BM_TOPOLOGY_RECORD toplgy ; while (heap->get_size () > 0) { if (! heap->remove (&i, (long ) &body) ) goto failure ;
// a safety check if (NULL == body) continue ;
// check if this body is already finished if (body->this_body_already_j?rocessed > 1) continue ;
// get body topology toplgy = body->get_adj_list () ; if (NULL == toplgy) continue ;
// check if the body is a face, if yes, memorize. if (body->is(BM_ENTITY_TYPE_FACE) ) { face2 = (BM_FACE ) body ;
// memorize to add this face to the connected component later idx_to_face_mapping[j++] = face2 ;
body->this_body_already_processed = 2 ;
55 APPENDIX C
// process all adjacent bodies for (current_face = (BM_FACE ♦) toplgy->get_first_face () ; current_face ; current_face = (BM_FACE ) toplgy->get_next faceO) {
/7 make sure that we don't process faces twice if (current_face->this_body_already_processed) continue ; if (! heap->insert (body_priority- - , (long) current_face) ) goto failure ; current_face->this_body_already_processed = 1 ;
// make sure we memorize the parent face index in the local spanning tree array c}urrent face->set_user_id(body->get_user_id()) ; for ( current_f orming = (BM_FORMING ) toplgy- >get_first_forming () ; current_f orming ; current_f orming = (BM_FORMING ) toplgy- >get_next_f orming () ) { if (current_f orming- >this_body_already_processed) continue ; if (! heap- >insert (body_priority- - , (long) current_f orming) ) goto failure ; current_f orming- >this_body_already_processed = 1 ;
// make sure we memorize the parent face index in the local spanning tree array if (body- >is (BM_ENTITY_TYPE_FACE) ) current_f orming- >set_user_id ( j - 1 ) ; e l s e current_f orming- >set_user_id (body- >get_user_id ( ) ) ; for (current_bendline = (BM_BENDLINE ) toplgy- >get_f irst_bendline () ; current_bendline ; current_bendline = (BM_BENDLINE ) toplgy- >get_next_bendline () ) { if (current_bendline->this_body_already_processed) continue ; if (! heap->insert (body_priority- - , (long) current_bendline) ) goto failure ; current_bendline->this_body_already_processed = 1 ;
// make sure we memorize the parent face index in the local spanning tree array if ( bo dy - > i s ( BM_ENT I T Y_T Y P E_F ACE ) ) current_bendline->set_user_id( j -1) ; e l s e current_bendline->set_user_id(body->get_user_id() ) ;
} }
56 APPENDIX C
// finally we need to compute contacts between this face and all other faces, that we postponed
// and add them to the connected component. long facel_id ; for (i = end_id ; i < j ; i++) { face2 = idx_to_face_mapping[i] ;
// first, compute distances in the TOPOLOGY GRAPH between this face (ie. face2)
// and all faces previously in the connected component. // we will use the parent face id in the local spanning tree array for that. facel_id = face2->get_user_id() ; // note : facel_id is the parent id of face2 (ie. there is a bendline between facel_id and face2 that we count) . if (dist_btw_faces && facel_id != i) { // if equal -> face2 has no parents,
// ie. a new connected component (must be start_id = end_id) .
// actually, it must be here true that facel_id < i for (k = start_id ; k < end_id ; k++) { set_face2face_dist (dist_btw_faces , number_of_f aces, dist_array_size, k, i, get_face2face_dist (dist_btw_faces,number_of_faces,dist_array_size , k, facel id) + 1) ;
' > ]
// else if equal, it must be that i == 'the end_id' in the beginning of this for-loop.
/ / not e that the next funct i on (add_face_to_connected_component ( ... ) ) will increment end_id. if (! add_face_to__connected_component (this, face2, &end id, all contacts, idx to face mapping)) goto failure ; } " - - -
// ok, the current connected component has no connections to the outside.
// try to expand the spanning tree, goto expand_spanning_tree ; done : ret_value = 1 ; goto release_memory_and_return ; failure :
57 APPENDIX C
ret_value = 0 ; release_memory_and_return :
// free memory if necessary for (i = 0 ; i < number_of_faces ; i++) { delete_contact_info_list (all_contacts [i] ) ■ if (all_contacts) delete [] all_contacts ; if (idx_to_face_mapping) delete [] idx_to_face_mapping ; if (heap) delete heap ; if (dist_btw_faces) delete [] dist_btw_f aces ; return ret value ;
58 APPENDIX D /////////////////////////////////////////////////////////////
' IJ /, Example of 2d Cleanup function. u//
' IJI, Copyright 1996 AmadaSoft America, Inc. "//
// //
/////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
#include <string.h>
/
Function Name :
1 control level
TestFindBoundary
TestFindDrawingSheetControl TestFindViewsControl
TestFindBoundaryControl TestFindArrowContro1 TestFindOneSideOpenControi TestFindOneSideOpen2Control TestFindCenterLineControl TestFindOneSideOpenConnectControl TestFindSameColorControl TestFindSelectSingleControl TestUnselectSingleControl TestClearControi TestClearKeepFlagsControl TestDeleteControl TestUndoControl TestUndoPreControl TestDeleteViewsControl TestSetUndoFlagViewsControl TestBackColorControl
2 applicate level
F2dCleanUpFindDrawingSheet F2dCleanUpFindViews
F2dCleanUpFindSameColorEntity
F2dCleanUpFindCenterLineEntity
F2dCleanUpFindOnesideOpenConnectEntity
F2dCleanUpFindOneSideOpenEntity2
F2dCleanUpClearDrawingEntity
F2dCleanUpDeleteDrawingEntity
F2dCleanUpDeleteViews APPENDIX D
F2dCleanUpUndo F2dCleanUpUndoPre
F2dCleanUpPickUpAllOneSideOpenEntity F2dCleanUpPickUpAllArcEntity F2dCleanUpFindLongestEntity F2dCleanUpFindGroup
F2dCleanUpCheckEntityExist
F2dCleanUpFindViewsRelation F2dCleanUpFindRelativeViews
F2dCleanUpFindOutSideLoop F2dCleanUpFindInSideEntity
F2dCleanUpFindOneSideOpenEntity F2dCleanUpFindGroupMinX F2dCleanUpFindOutNextEntity F2dCleanUpFindOnesideOpenConnectEntityNext
F2dCleanUpFindArrow
F2dCleanUpFindArrowOneSideOpenEntity
F2dCleanUpFindArrowEndEntity
F2dCleanUpCheckStartEndEntity
F2dCleanUpComputeCenterLineAngle
F2dCleanUpFindArrowCenterEntity
F2dCleanUpChangeArrowVertexFlag
F2dCleanUpArcAngle
F2dCleanUpLineAngle
F2dCleanUpLineLength
F2dCleanUpChangeColor
F2dCleanUpChangeDrawingColor
F2dCleanUpChangeChildrenFlag
F2dCleanUpChangeDrawingFlag
F2dCleanUpClearDrawingKeepFlags
F2dVector F2dVectorUnit F2dDistancePointLine __ ============™=============.
#ifdef VELLUM
#include "ck_cdlc.h"
// VCI_VLM.DLL include files
#include "system.h"
// CadKey emulation files #include "vim ck.h" APPENDIX D
#endif
#ifdef CKWIN
#include "ck_cdlc.h"
#include "ck_cde.h"
#include <ckcdll.h>
#include <ck_attr.h>
#define ck_setattr2 ck_setattr
#endif
#ifdef AUTOCAD #include <ACAD_VCI.H> #endif
// 2d3d files
#include "view3D.h"
//#include "Proto.h" // includes prototypes of all functions.
#define VLM_ID_2DT03D 32 #define Regular 0 #define ThreeViews 1 //#define SECURITY
// Some definitions
//
#undef DEBUG
//
// Following is the definition of the global variables
//
#ifdef CKWIN int TopViewNum, IsometricViewNum;
// These variables are used only with CADKEY when changing to
TopView or Isometric view.
#endif
// by Ji Feb.14, 1996 double F2dCleanUpTolerance = 0.01;
// undo flag ( set a No. for views ) extern int F2dCleanUpExcutedNo = 0; extern int WorkLevel, TrimLevel, VW3DLevel;
// Three layers are useD: WorkLevel is used to highlight views and display temporary drawings.
// TrimLevel is used to store the trimmed drawing.
// VW3DLevel is used to store the projected APPENDIX D
3D drawing.
// these are the four drawings used. extern struct drawing input_drawing, projected_drawing, trim_drawing, final_drawing;
// Three drawing structures are constructed:
// InputDrawing is constructed from the input entities
// taken from from all the layers that are turned on.
// TrimmedDrawing is constructed from the trimmed entities. Once the
// Trimmed Drawing is constructed, the Input Drawing is not used.
// ProjectedDrawing is constructed from the entities projected in a single flange.
// If 'DoneProjection' is selected, then these entities are saved on VW3DLevel.
// If 'UndoProjection' is selected, these entities are discarded. extern struct planar_flange AllFlanges; // this is a pointer to the list of flanges extern char Messages [MaxMessages] [80] ;
// This array stores the messages read from the message file. extern int message_flag;
// This variable is assigned to '1' if the messages were read successfully from the message file.
// Otherwise, it is set to '0' . extern int number_of_views;
// This vairbale stores the number of disconnected components discovered in the ♦inputs drawing. extern int number_of_entities;
// This variable stores the number of entities loaded for the current drawing. extern int number_trimmed_entities;
// This variable stores the number of entities loaded for the trimmed drawing. extern int n_edges;
// This variable stores the number of connecting edges between the trimmed entities. extern double MatchTolerance, ConnectivityTolerance;
// ConnectivityTolerance is used to determine whether two entities APPENDIX D are close enough to be considered connected.
// Matching Tolerance is used to determine whether two entities on different views are matching. extern double ArrowHeadAngle, ArrowHeadLength;
// These variuables define the structure of an arrow for the 2D clean up funciton. extern double view_boundaries [MaxNumberOfViews+1] [4] ;
// This array is used to store the bounding box of each connected component of the input drawing.
// once the views are detected, several components might be mapped to a single view. extern int type_of_view [MaxNumberOfViews+1] ;
// This array maps every view to its type, namely to one of Top,
Left, Right, Front, Back view.
// Its content is valid only after 'DoneViews' was called.
//int view_rotation_flag[MaxNumberOfViews+1] ;
// This array is used for marking rotated views.
// If the i'th element is ' 1 ' then the view is rotated.
//extern static char original_lvmask [32] ;
// At the beginning we save the (on,off) status of all the layers.
//extern static char twoDmask[32] ;
//extern static char threeDmask [32] ;
// The masks used to display the 2D and 3D models.
//extern static int original_worklevel ;
// Specifies the original work level of the user when fold is started
// static int original_setup_available = 0 ;
// true iff original (layer) setup is available, ie . can be restored
extern int dialog_open_flag = 0;
// This variable is a flag which specifies whether some dialog boxes were opened.
extern int AtrimLineTypeSwitch, AtrimColorSwitch, AtrimWidthSwitch,
AtrimCenterLineSwitch;
// these switches are used to specify in which cases AutoTrim will trim lines. APPENDIX D
//struct node F2dCleanUpInputEntity(char , struct drawing ) ; //static int select_flange (struct resbuf rb) ; typedef struct Vector { double x,y,z;
}; extern double BBminX,BBmaxX,BBminY,BBmaxY,BBminZ,BBmaxZ;
/*
Function:
Name : TestFindBoundary
Description:
It is a manual function. When user selected a boundary's entity of a view, the function would find all of the connected entities for the view.
Return Value:
< 0 : Error = 0 : No proccess
> 0: Completed successfully; the Number is the counter of found entities.
Parameters : Subfunctions: int F2dCleanUpFindArrow look for arrow type entity int F2dCleanUpFindArrowEndEntity find arrow end line int F2dCleanUpFindArrowCenterEntity find arrow center line int F2dCleanUpFindArrowOneSideOpenEntity find one side open entity for arrow type int F2dCleanUpComputeCenterLineAngle compute center line angle int F2dCleanUpCheckStartEndEntity check start and end entities int F2dCleanUpFind0utSideLoop look for out side loop entities int F2dCleanUpFind0utNextEntity look for connected entity with out side loop entities struct node F2dCleanUpFindGroupMinX look for minimum X-value for a entities group struct node_list F2dCleanUpFindGroup look for a group entities connected with input entity APPENDIX D struct node F2dCleanUpInputEntity ( old function ) look for a selected entity on screen int F2dCleanUpLineAngle compute a line type entity's angle int F2dCleanUpArcAngle compute a arc type entity's angle, int F2dCleanUpChangeChildrenFlag change entity's children flags int F2dCleanUpChangeArrowVertexFlag change arrow top vertex's flags and set arrow center line coordinates int F2dCleanUpChangeColor change entity' s color int F2dCleanUpFindOneSideOpenEntity look for one side open entities and they are vertical with arrow type entities double F2dCleanUpLineLength compute line type entity's length
*/ int TestFindBoundary()
{
// external functions int F2dCleanUpFindArrow() ; int F2dCleanUpChangeColor () ; int F2dCleanUpFindOneSideOpenEntity() ; int F2dCleanUpFind0utSideLoop() ; int F2dCleanUpChangeDrawingColor () ; struct node F2dCleanUpInputEntity0 ; struct node ♦F2dCleanUpFindGroupMinX() ; struct node_list ♦F2dCleanUpFindGroup() ;
// entities counter and flags int count = 0, assistant_line_flag = 0; // link list and temp list struct node_list
♦Entities_change_color_listl; // selected entity and temp entities struct node
♦entity,
MinXvalueEntity;
// Begin li¬ lt Step_l:
// check the number of entites
// get count of all entities
// if an error occurred, exit immidiately. APPENDIX D if (number_of_entities<0) return -1; for( ; ; ) { /
// Step_2 : select one entity entity = F2dCleanUpInputEntity( "Select a Boundary Entity
Figure imgf000277_0001
// check a flag for outside loop process if ( count < 1 ) continue;
MinXvalueEntity = F2dCleanUpFindGroupMinX (
Entities_change_color_listl) ; if ( MinXvalueEntity == 0 ) continue;
// Step_7:
// find outside loop entities
F2dCleanUpFind0utSideLoop( MinXvalueEntity ) ; //
// Step_X:
// change color to Magenta for a selected boundary
// turn off input levels ck_levels(CK_OFF, 1,255) ; #ifdef CKWIN
F2dCleanUpChangeColor(Entities_change color listl) ; #endif #ifdef VELLUM
F2dCleanUpChangeDrawingColor(&trim_drawing) ; #endif
// clear a flag for outside loop process assistant_line_flag = 0;
// turn ON the level used to store the trimmed entities. ck_levels (CK_ON,TrimLevel, TrimLevel) ; #ifdef CKWIN
8 APPENDIX D if ( SwitchRedraw == 1 ) ck redraw( CK PRIME VP ) ; #endif
} return count;
} /*
Function:
Name : F2dCleanUpFindGroup
Description: look for a group entities connected with input entity Return Value:
= 0: Completed successfully; Parameters :
Input :
Entity: a entity
Output:
NodeList: a node list connected with input entity
*/ struct node_list ♦F2dCleanUpFindGroup (struct node Entity, int ^Cnt
)
{
// entities counter and flags int count = 0;
// link list and temp list struct node_list
♦EntitiesListl,
Figure imgf000278_0001
// initialize
EntitiesListl = ( struct node_list ♦ ) calloc ( 1, sizeof ( struct node_list
) ) ; open_list = ( struct node_list ) calloc ( 1, sizeof ( struct node list ) ) ;
// set a flag for the boundary entity count = 0;
// set pointer to first entity open_list->car = Entity;
// set a open flag to the node APPENDIX D open_list->car->flags = 1; // set link address open_list->cdr = NULL;
// set the pointer to output node list EntitiesListl->car = open_list->car; EntitiesListl->cdr = open_list->cdr;
// Step_3 :
// find connected entities for ( temp_list = open_list;
( temp_list
// && (temp_list->cdr != 0)
> ;
) { if ( temp_list->car == NULL ) break;
// get a pointer from open list
Next_entity = temp_list->car;
// set a closed flag to the node
Next_entity->flags = 2;
// close the node ( delete the node from open list ) open_list = open_list->cdr;
// count the number of entities count++;
// look for first connected entity whose flags=0. for (temp_listl=Next_entity->connected_nodes; // temp_listl && temp_listl->car->flags==l; ( temp_listl!=0 && temp_listl->car!=0 ); temp_listl=temp_listl->cdr) { if ( temp_listl->car == NULL ) break; // if found an unmarked connected entity if (temp_listl
&& temp_listl->car->flags==0
& & E n t i t y - > l i n e _ t y p e = = temp_listl->car->line_type
&& Entity->color == temp_listl->car->color & & E n t i t y - > i s_t h i c ne s s = = temp__listl->car->is thickness
)" {
// allocate memory for open list element open_temp_list = ( struct node_list ♦ ) calloc ( 1, sizeof ( struct node_list ) ) ;
// allocate memory for output node list element
Out_temp_list = ( struct node_list ♦ ) calloc ( 1, sizeof ( struct node_list )) ;
// add this entity to the open list open_temp_list->car = temp_listl->car;
10 APPENDIX D
// add this entity to the output node list Out_temp_list->car = temp_listl->car;
// set a open flag to the node open_temp_list->car->flags = 1;
// connect to the open list open_temp_list->cdr = open_list;
// move the pointer of open list to the top open_list = open_temp_list;
// connect to the output node list
Out_temp_list->cdr = EntitiesListl;
// move the pointer of output node list to the top
EntitiesListl = Out_temp_list;
}
}
// assign value to the loop variable temp list = open list;
}
Cnt = count; return EntitiesListl;
Function:
Name : F2dCleanUpArcAngle
Description: compute a arc type entity's angle. Return Value:
RotateVertexFlag: direction flag =1: vertexl is rotate point =2 : vertex2 is rotate point Parameters:
Input :
1 OriginVertex: rotationary vertex
2 Entity: arc type entity Output :
1 EntityAngle: direction angle ( radian )
2 EntityAngleAnother: another side direction angle
*/ int F2dCleanUpArcAngle ( // input
11 APPENDIX D struct planar_vertex OriginVertex, struct node Entity,
// output double EntityAngle, double ♦EntityAngleAnother )
/ {/ return value int RotateVertexFlag=0;
// length and angle double Tolerance = 0.0;
// set tolerance
Tolerance = F2dCleanUpTolerance;
// select connected side of entity if ( Entity->vertexl == OriginVertex ) {
// get arc start-angle
// ( direction : from circle-center to start-point
)
RotateVertexFlag = 1;
♦EntityAngle = ( Entity->AngBegin ) pi / 180.0;
// change angle to oppsite direction
// ( direction : from start-point to circle-center
)
EntityAngle = ♦EntityAngle + pi;
// check angle if ( EntityAngle >(2.0*pi)) EntityAngle = ♦EntityAngle
- 2.0^pi; if ( fabs (EntityAngle-2.0*pi) < Tolerance ) ♦EntityAngle = 0.0;
// compute tangent line angle for the arc end-angle
// ( direction : from start-point to end-point )
EntityAngle = EntityAngle + 1.5 pi;
// check angle if ( EntityAngle >(2.0^pi)) EntityAngle = ♦EntityAngle
- 2.0^pi; if ( fabs (*EntityAngle-2.0*pi) < Tolerance ) ♦EntityAngle = 0.0;
// get another side data
// get arc start-angle
// ( direction : from circle-center to end-point
)
EntityAngleAnother = ( Entity->AngEnd ) ♦ pi / 180.0;
// change angle to oppsite direction
// ( direction : from end-point to circle-center
)
EntityAngleAnother = EntityAngleAnother + pi; // check angle if ( EntityAngleAnother > 2.0^pi ) EntityAngleAnother = EntityAngleAnother - 2.0 ♦ pi;
12 APPENDIX D else if ( fabs (♦EntityAngleAnother-2.O^pi) < Tolerance ) ♦EntityAngleAnother = 0.0;
// compute tangent line angle for the arc end-angle // ( direction : from end-point to start-point ) ♦EntityAngleAnother = EntityAngleAnother + 0.5 pi;
// check angle if ( ♦EntityAngleAnother > 2.0^pi ) ♦EntityAngleAnother = ♦EntityAngleAnother - 2.0 pi; else if ( fabs (EntityAngleAnother-2. O^pi) < Tolerance ) ♦EntityAngleAnother = 0.0;
} else {
// get arc end-angle
// ( direction : from circle-center to end-point
)
RotateVertexFlag = 2;
♦EntityAngle = ( Entity->AngEnd ) pi / 180.0;
// change angle to oppsite direction
// ( direction : from end-point to circle-center
)
EntityAngle = EntityAngle + pi; if ( ♦EntityAngle > 2.0^pi ) EntityAngle = EntityAngle
- 2.0*pi; if ( fabs (EntityAngle - 2.0pi) < Tolerance ) ♦EntityAngle = 0.0;
// compute tangent line angle for the arc end-angle // ( direction : from end-point to start-point ) EntityAngle = EntityAngle + 0.5 pi; if ( EntityAngle > 2.0^pi ) EntityAngle = EntityAngle
- 2.0^pi; if ( fabs (EntityAngle - 2.0^pi) < Tolerance ) EntityAngle = 0.0;
// get another side data
// get arc start-angle
// ( direction : from circle-center to start-point
♦EntityAngleAnother = ( Entity->AngBegin ) pi /
180.0,
// change angle to oppsite direction
// ( direction : from start-point to circle-center
♦EntityAngleAnother = EntityAngleAnother + pi; if ( ♦EntityAngleAnother > 2. O^ i ) ♦EntityAngleAnother = EntityAngleAnother - 2.0 pi; if ( fabs (♦EntityAngleAnother - 2.0^pi ) < Tolerance ) ♦EntityAngleAnother = 0.0;
// compute tangent line angle for the arc start-angle
// ( direction : from start-point to end-point )
13 APPENDIX D
♦EntityAngleAnother = EntityAngleAnother + 1.5 pi; if ( ♦EntityAngleAnother > 2.0^pi ) ♦EntityAngleAnother = ♦EntityAngleAnother - 2.0 pi; if ( fabs (♦EntityAngleAnother - 2.0^pi ) < Tolerance ) ♦EntityAngleAnother = 0.0;
}
// the end of this function return RotateVertexFlag; }
/*
Function:
Name : F2dCleanUpLineAngle
Description:
It is a function for control how to compute a line type entity's angle. Return Value:
RotateVertexFlag: direction flag =1: vertexl is rotate point =2 : vertex2 is rotate point Parameters:
Input:
1 OriginVertex: rotationary vertex
2 Entity: line type entity Output:
1 EntityAngle: direction angle ( radian )
2 EntityAngleAnother: another side direction angle
__ int F2dCleanUpLineAngle( // input struct planar_vertex OriginVertex, struct node Entity, // output double EntityAngle, double EntityAngleAnother )
{
// return value int RotateVertexFlag=0; // selected entity and temp entities struct planar_vertex VertexTemp, VertexAnotherTemp; // length and angle double diff_x = 0.0,
14 APPENDIX D diff_y = 0.0, Tolerance = 0.0; // set tolerance Tolerance = F2dCleanUpTolerance; // select connected side of entity if ( Entity->vertexl == OriginVertex ) {
// get vertexl->vertex2
RotateVertexFlag = 1;
VertexTemp = Entity->vertexl;
VertexAnotherTemp = Entity->vertex2; else { // get vertex2->vertexl RotateVertexFlag = 2;
VertexTemp = Entity->vertex2;
VertexAnotherTemp = Entity->vertexl;
}
// compute angle if ( fabs ( VertexTemp->X - VertexAnotherTemp->X ) < Tolerance
) (
// angle = 0.5 pi if ( VertexTemp->Y < VertexAnotherTemp->Y )
EntityAngle = 0.5 pi;
// angle = 1.5 pi else ♦EntityAngle = 1.5 ♦ pi; else { // -pi < angle < pi diff_y = VertexAnotherTemp->Y - VertexTemp->Y; if ( fabs ( diff_y ) > Tolerance ) { diff_x = VertexAnotherTemp->X - VertexTemp->X; EntityAngle = atan2 ( diff_y, diff_x ) ; // -pi < angle < 0.0 if ( EntityAngle < 0.0 ) EntityAngle ♦EntityAngle + 2.0#pi; else { // angle = 0.0 or pi if ( VertexAnotherTemp->X > VertexTemp->X ) EntityAngle = 0.0; else EntityAngle = pi;
if ( fabs (EntityAngle - 2.0*pi) < Tolerance ) EntityAngle =
0.0;
// get another side angle
EntityAngleAnother = EntityAngle + pi;
// check angle if ( EntityAngleAnother > ( 2.0 pi ) ) {
EntityAngleAnother = EntityAngleAnother - 2.0 pi, if ( fabs (EntityAngleAnother - 2.0pi) < Tolerance ) { EntityAngleAnother = 0.0;
15 APPENDIX D
}
// the end of this function return RotateVertexFlag;
Function:
Name : F2dCleanUpChangeColor
Description:
It is a function for changing entity's color. Return Value:
= 0: Completed successfully; Parameters :
Input :
Entities_change_color_list : a node list that will be changed color
*/ int F2dCleanUpChangeColor ( struct node_l i st
♦Entities change color list)
{
// link list and temp list struct node_list
Color_temp_list; // selected entity and temp entities struct node
Next_entity; // entity's specifitys CK_ENTATT attr; // specificity of entities int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Change Color Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
#ifdef VELLUM
// clear views highlighting ck_erase_level ("VW_2D") ; // ck_erase_level ("VW TRIM"); #endif
// check all of entities on the list for( Color_temp_list=Entities_change_color_list;
16 APPENDIX D
Color_temp_list;
Color_temp_list = Color_temp_list->cdr) { if ( Color_temp_list->car == NULL ) break; Next_entity = Color_temp_list->car; switch ( Next entity->flags )
{ case 1: attr.color = CK_GREEN; ck_setattr( Next_entity->id, CK_COLOR, NULL,
&attr break; case 3 : attr.color = CK_GRAY; ck_setattr( Next_entity->id, CK_COLOR, NULL,
&attr ) break; case 4 : attr.color = CK_MAGENTA; ck_setattr( Next_entity->id, CK_COLOR, NULL,
&attr ) ; break;
}
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished change color Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif return 0;
} /*
Function:
Name : F2dCleanUpChangeDrawingColor
Description:
It is a function for changing entity's color. Return Value:
= 0: Completed successfully; Parameters:
Input :
1 In_drawing: drawing that will be changed color __ int F2dCleanUpChangeDrawingColor(struct drawing In_drawing)
17 APPENDIX D
// extern functions void draw_entity0 ;
// selected entity and temp entities struct node entity; int CountPrompt = 0; char message [64] ;
// entity's specifitys
CK_ENTATT attr; // specificity of entities
#ifdef VELLUM
// clear views highlighting ck_erase_level ("VW_2D") ; // ck_erase_level ( "VW TRIM") ; CountPrompt++; sprintf ( message, "Start Change Color Sheet Entity %d", CountPrompt ) ; ck_prompt ( message ) ; #endif
// check all of entities on the list for( entity=In_drawing->objects; entity; entity = entity->next) { switch ( entity->flags )
#ifdef VELLUM case 0 : draw_entity( entity, entity->color ); break; case 1: draw_entity( entity, CK_GREEN ) ; break; case 2 : draw_entity( entity, entity->color ) ; break; case 3 : draw_entity( entity, CK_BLUE ) ; break; case 4 : draw_entity( entity, CK_MAGENTA ) ; break; case 5 : draw_entity( entity, entity->color ) ; break; case 6 : draw_entity( entity, CK_RED ) ; break; case 7 : draw_entity( entity, CK_YELLOW ) ; break;
18 APPENDIX D case 8 : draw_entity( entity, entity->color ) ; break; case 9: draw_entity( entity, entity->color ) ; break; case 10: draw_entity( entity, CK_CYAN ) ; break; case 11: draw_entity( entity, entity->color ) ; break; #endif #ifdef CKWIN case 1 : attr.color = CK_L_GREEN; ck_setattr( entity->id, CK_COLOR, NULL, fcattr
) ; break; case 3 : attr.color = CK_L_GRAY; ck_setattr( entity->id, CK_COLOR, NULL, kattr
) ; break; case 4 : attr.color = CK_MAGENTA; ck_setattr( entity->id, CK_COLOR, NULL, &attr
) ; break; case 6 : attr.color = CK_L_RED; ck_setattr( entity->id, CK_COLOR, NULL, &attr
) ; break; case 7 : attr.color = CK_YELLOW; ck_setattr( entity->id, CK_C0LOR, NULL, &attr
) ; break; case 10: attr.color = CK_L_CYAN; ck_setattr( entity->id, CK_COLOR, NULL, kattr
) ; break; #endif
} if ( entity->next == NULL ) break;
} #ifdef VELLUM
19 APPENDIX D
CountPrompt++; sprintf ( message, "Finished change color Sheet Entity %d", CountPrompt ) ; ck_prompt ( message ) ; #endif return 0;
} /*
Function:
Name : F2dCleanUpUndoPre
Description:
To prepare data flags for undo function. Return Value :
= 0: Completed successfully; Parameters:
Input :
1 In_drawing: drawing that will be changed status
*/ int F2dCleanUpUndoPre (struct drawing +In drawing)
{
// selected entity and temp entities struct node ♦entity;
// set flag F2dCleanUpExcutedNo = 2; // check all of entities on the list for( entity=In_drawing->objects; entity; entity entity->next) ( entity->status = entity->flags; if ( entity->next == NULL ) break;
} return 0;
} /*
Function:
Name : F2dCleanUpUndo
Description:
To undo. Return Value:
= 0: Completed successfully; Parameters:
Input:
20 APPENDIX D 1 In_drawing: drawing that will be undoed status
*/ int F2dCleanUpUndo (struct drawing In_drawing)
{
// selected entity and temp entities struct node entity;
// flag int NoChangeFlag = 0;
// check flag if ( F2dCleanUpExcutedNo == 0 ) return NoChangeFlag;
// check all of entities on the list for( entity=In_drawing->objects; entity; entity entity->next) { if ( entity->status != entity->flags ) { NoChangeFlag = 1; entity->flags = entity->status;
} if ( entity->next == NULL ) break;
}
// check views flag if ( F2dCleanUpExcutedNo == 1 ) In_drawing->views
NULL;
// reset flag for views
F2dCleanUpExcutedNo = 0; return NoChangeFlag;
} /*
Function:
Name : F2dCleanUpChangeDrawingFlag
Description:
It is a function for changing entity's flag. Return Value :
= 0: Completed successfully; Parameters:
Input :
1 In_drawing: drawing that will be changed color __ int F2dCleanUpChangeDrawingFlag(struct drawing ♦In_drawing)
// selected entity and temp entities
21 APPENDIX D struct node entity; int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Flag Sheet Entity %d" CountPrompt ) ; ckjprompt ( message ) ; #endif
// check all of entities on the list for( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity->flags == 4 ) entity->flags = 3; #ifdef VELLUM
//CountPrompt++;
//sprintf ( message, "Flag Sheet Entity %d", CountPrompt ) //ck_prompt ( message ) ; #endif if ( entity->next == NULL ) break;
} #ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished Flag Sheet Entity %d" CountPrompt ) ; ck_prompt ( message ) ; #endif return 0;
} /*
Function:
Name : F2dCleanUpFindSameColorEntity
Description: find same color entity. Return Value:
= 0 : Completed successfully; Parameters:
Input :
1 In_entity: an entity
2 ln_drawing: drawing that will be changed color -- =======--===.-=========.====== int F2dCleanUpFindSameColorEntity( struct node In_entity, struct drawing ♦In_drawing)
22 APPENDIX D
// selected entity and temp entities struct node entity; int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find same color Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
// check all of entities on the list for( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity->color == In_entity->color
&& entity->flags == 0) entity->flags = 3; if ( entity->next == NULL ) break;
}
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished find same color Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif return 0;
} /*
Function:
Name : F2dCleanUpClearDrawingEntity
Description:
It is a function for return entity's color. Return Value:
= 0: Completed successfully; Parameters:
Input:
1 In_drawing: drawing that will be changed color
i *nt"F2dCleanUpClearDrawingEntity(struct drawing In drawing)
{
// selected entity and temp entities struct node entity;
23 APPENDIX D
// entity's specifitys
CK ENTATT attr; // specificity of entities int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
// clear views highlighting ck_erase_level ("VW_2D" ) ; // ck_erase_level ("VW_TRIM") ; // CountPrompt++;
// sprintf ( message, "Start Clear Entity %d", CountPrompt // ck_prompt ( message ) ; #endif
// check all of entities on the list for ( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity == NULL ) break; switch ( entity->flags ) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10 entity->flags = 0; draw_entity( entity, entity->color ) ; //attr.color = entity->color;
//ck_setattr( entity->id, CK_COLOR, NULL, &attr ) ; default: break;
#ifdef VELLUM
// CountPrompt++;
// sprintf ( message, "Finished clear Entity d", CountPrompt
// ck_prompt ( message ) #endif
// clear views connected
In_drawing->views = NULL;
24 APPENDIX D return 0;
}
Function:
Name : F2dCleanUpClearDrawingKeepFlags
Description:
To return entity's color but keep flags. Return Value :
= 0: Completed successfully; Parameters:
Input :
1 In_drawing: drawing that will be changed color __ int F2dCleanUpClearDrawingKeepFlags (struct drawing ^In drawing)
{
// selected entity and temp entities struct node entity;
// entity's specifitys
CK_ENTATT attr; // specificity of entities int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
// clear views highlighting ck_erase_level ( "VW_2D") ; #endif
// check all of entities on the list for ( entity=In_drawing->objects; entity; entity = entity->next) { switch ( entity->flags )
{ case 0 case 1 case 2 case 3 case 4 case 5 case 6 case 7 case 8 case 9 case 10 : // center line
25 APPENDIX D draw_entity( entity, entity->color ) ;
//attr.color = entity->color;
//ck setattr( entity->id, CK_COLOR, NULL, kattr
) ;
} if ( entity->next == NULL ) break;
} return 0;
} /*
Function:
Name : F2dCleanUpDeleteViews
Description:
It is a function for delete views. Return Value:
= 0 : Completed successfully; Parameters:
Input :
1 In_drawing: drawing
*/ int F2dCleanUpDeleteViews (struct drawing AIn drawing)
{
// check drawing if ( In_drawing == NULL ) return 0;
// delete views ( Not release memory ) In_drawing->views == NULL; return 0;
}
Function:
Name : F2dCleanUpDeleteDrawingEntity
Description:
It is a function for delete entities. Return Value:
= 0: Completed successfully; Parameters:
Input :
1 In_drawing: drawing
*7 ============ int F2dCleanUpDeleteDrawingEntity(struct drawing ♦In_drawing)
26 APPENDIX D
// selected entity and temp entities struct node entity; struct group Gp; // group struct node_list ETL; // Entity Temp List int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Delete Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
// check all of entities on the list for ( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity->flags == 3 | j entity->flags == 6
I j entity->flags == 0 j j entity->flags == 10 ) ( #ifdef CKWIN ck_delent ( entity->id ) ; #endif
#ifdef VELLUM
// remove_entity ( entity, In_drawing ) ;
#endif entity->flags = 99;
} if ( entity->next == NULL ) break;
} if ( In_drawing->views == NULL ) return 0; // unuse group entities for( Gp=In_drawing->views; Gp; Gp = Gp->next) { if ( Gp == NULL ) break; if ( Gp->index != 0 ) continue; for ( ETL = Gp->entities; ETL; ETL = ETL->cdr ) { #ifdef CKWIN ck_delent ( ETL->car->id ) ; #endif #ifdef VELLUM
// remove_entity ( ETL->car, In_drawing ) ;
#endif
ETL->car->flags = 99; if ( ETL->cdr == NULL ) break;
} if ( Gp->next == NULL ) break;
}
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished Delete Entity %d" , CountPrompt ) ;
27 APPENDIX D ck_prompt ( message ) ;
#endif return 0;
} /*
Function:
Name : F2dCleanUpCheckEntityExist
Description: check an entity for current drawing if the entity is not same to database, drawing was changed
Return Value:
= 0 : No change;
= 1: Changed; Parameters:
Input :
1 In_drawing: drawing
__ int F2dCleanUpCheckEntityExist (struct drawing In_drawing)
// selected entity and temp entities struct node entity;
// define int ReturnCode = 0, etype = 0; double Xl=0.0,yl=0.0,zl=0.0,x2=0.0,y2=0.0,z2=0.0, rad=0.0,angl=0.0,ang2=0.0; // entity's specifitys CK_ENTATT attr; // specificity of entities
// check all of entities on the list if ( In_drawing->objects == NULL ) return 1; for( entity=In_drawing->objects; entity; entity = entity->next) ( if ( entity->flags == 99 ) continue; ReturnCode = ck_getentid( entity->id, ketype ) ; if ( ReturnCode == CK_N0_ENT ) return 1; else {
// check all of entities on the list switch ( entity->type )
{ case CK_ARC : ck_getarc ( entity- >id ,
&xl , &yl , &zl ,
&ra d , &an g l , & ang 2 , 28 APPENDIX D
&attr ) ; break; case CK_LINE: ck_getline ( entity->id, &xl, δ-yl, ScZl,
&x2 , &y2 , &z2 , fcattr ) ; break;
} if ( attr. level == 191 ) return 0; else return 1;
} if ( entity->next == NULL ) break;
} return 1;
}
Function:
Name : F2dCleanUpChangeArrowVertexFlag
Description: to change arrow top vertex's flags and set arrow center line coordinates. Return Value:
= 0: Completed successfully; Parameters:
Input :
1 Flags: flag
2 TopVertex: arrow top vertex
3 Entity: arrow center line entity
*/ int F2dCleanUpChangeArrowVertexFlag(
// input int flags, struct planar_vertex TopVertex, struct node Entity)
{
// set flag to arrow top vertex TopVertex->flags = flags; // set arrow center line coordinates TopVertex->ArrowCenterLine_Xl = Entity->X1 TopVertex->ArrowCenterLine_Yl = Entity->Y1 TopVertex->ArrowCenterLine_Zl = Entity->Z1 TopVertex->ArrowCenterLine_X2 = Entity->X2 TopVertex->ArrowCenterLine_Y2 = Entity->Y2 TopVertex->ArrowCenterLine_Z2 = Entity->Z2 // end return 0;
29 APPENDIX D
Function:
Name : F2dCleanUpFindArrowCenterEntity
Description: to find arrow center line and set flags to arrow's members. Return Value:
= 0 : No arrow;
= 1 : Arrow Parameters :
Input :
1 Nodes : connected node
2 TopVertex: arrow top vertex
3 StartEntity: arrow start line entity
4 EndEntity: arrow end line entity
5 CenterLineAngleTemp: arrow center line angle
*/ int F2dCleanUpFindArrowCenterEntity( // input struct node_list Nodes, struct planar_vertex TopVertex, struct node StartEntity, struct node EndEntity, double CenterLineAngleTemp )
{
// external functions int F2dCleanUpLineAngle () ; int F2dCleanUpChangeChildrenFlag() ; int F2dCleanUpChangeArrowVertexFlag() ; double F2dCleanUpLineLength() ; // nodes struct node CenterEntity; // link list and temp list struct node_list temp_list; // flags int ReturnFlag = 0, ArrowFlags = 3; // double double CenterParentLength = 0.0, CenterParentAngle = 0.0, CenterParentAngleAnother = 0.0; double Tolerance = 0.0;
// set value
Tolerance = F2dCleanUpTolerance;
// look for arrow center line
30 APPENDIX D for ( temp_list = Nodes; temp_list; temp_list = temp_list->cdr) { // check pointer address if ( StartEntity == temp_list->car
I j EndEntity == temp_list->car ) continue; // get new entity CenterEntity = temp_list->car;
// check flags
// if ( CenterEntity->flags != 2
II ScS CenterEntity->flags != 3 ) continue; if ( CenterEntity->type != CK_LINE ) continue; if ( CenterEntity->line_type != StartEntity->line_type && CenterEntity->color !
StartEntity- > ■c )lor
& & CenterEntity- >is__thickness ! =
StartEntity- >is_thickness ) continue; if ( CenterEntity->no_connected_l < 2
&& CenterEntity- >no_connected_2 < 2 ) continue; // check length
Cent erParent Length = F2dCleanUpLineLengt h (
CenterEntity- >parent ) ; if ( CenterParentLength < Tolerance ) continue; // arrow central-entity angle F2dCleanUpLineAngle ( // input
TopVertex, CenterEntity->parent, // output
&CenterParentAngle, ScCenterParentAngleAnother ) ; // check the angle for central entity if ( fabs ( CenterParentAngle - CenterLineAngleTemp )
> Tolerance ) continue; // set flags for arrow's entities ReturnFlag = 1;
// look for arrow entity's children F2dCleanUpChangeChildrenFlag( StartEntity->parent ) ; F2dCleanUpChangeChildrenFlag( EndEntity->parent ) ; F2dCleanUpChangeChildrenFlag( CenterEntity->parent ) ; // set flag to arrow top vertex F2dCleanUpChangeArrowVertexFlag( SArrowFlags,
TopVertex, CenterEntity ) ; return ReturnFlag; if ( temp list->cdr == NULL ) break;
} return ReturnFlag;
} /*
31 APPENDIX D
Function:
Name : F2dCleanUpFindArrowOneSideOpenEntity
Description: to find one side open entity Return Value:
= 0: No open;
= 1: open
= 2: open
Parameters:
Input:
1 Nodes: connected node
i *n7t F2dCleanUpFindArrowOneSideOpenEntity( struct node_list Nodes
)
{
// link list and temp list struct node_list temp_list; // entities counter and flags int open_entity_flag = 0; // start for ( temp_list = Nodes; temp_list; temp_list = temp_list->cdr) { // ckeck another side connected' s counter if { temp_list->car->no_connected_l == 0
&& temp_list->car->no_connected_2 > 1 ) { open_entity_flag = 1; break;
} if ( temp_list->car->no_connected_2 == 0
&& temp_list->car->no_connected_l > 1 ) { open_entity_flag = 2; break;
} if ( temp_list->cdr == NULL ) break; return open_entity_flag;
Function:
Name : F2dCleanUpCheckStartEndEntity
Description: to check start and end entities Return Value:
= 0: No arrow;
32 APPENDIX D
= 1: good Parameters :
Input:
1 StartEntity: arrow start line entity
2 EndEntity: arrow end line entity
__ int F2dCleanUpCheckStartEndEntity( // input struct node StartEntity, struct node EndEntity )
{
// external functions double F2dCleanUpLineLength() ;
// double double arrow_start_parent_length = 0.0, arrow_end_parent_length = 0.0, arrow_tolerance = 0.0; // set tolerance arrow_tolerance = F2dCleanUpTolerance;
// start
// compute entities' parent length arrow_start_parent_length = F2dCleanUpLineLength( StartEntity
) ; arrow_end_parent_length = F2dCleanUpLineLength( EndEntity ) ;
// check length if ( arrow_start_parent_length < arrow_tolerance ) return 0; if ( arrow_end_parent_length < arrow_tolerance ) return 0;
// check tloerance if ( fabs ( arrow_start_parent_length - arrow_end_parent_length
)
> arrow_tolerance ) return 0; // check angle : if entities are parallel, STOP if (sqrt (fabs( ( ( StartEntity->X1 - StartEntity->X2 )
( EndEntity->Y1 - EndEntity->Y2 )) -(( EndEntity->X1 - EndEntity->X2 )
♦ ( StartEntity->Y1 - StartEntity->Y2 )) ) ) < arrow_tolerance ) return 0;
// normal end return 1,-
} /*
Function:
Name : F2dCleanUpComputeCenterLineAngle
33 APPENDIX D
Description: to compute center line angle Return Value:
= 0 : No arrow;
= 1 : good Parameters :
Input :
1 TopVertex: arrow top vertex
2 StartEntity: arrow start line entity
3 EndEntity: arrow end line entity Output:
1 CenterLineAngle : arrow center line angle
i *n7t F2dCleanUpComputeCenterLineAngle{
// input struct planar_vertex ^TopVertex, struct node StartEntity, struct node EndEntity,
// output double ♦CenterLineAngle )
{
// external functions int F2dCleanUpLineAngle () ;
// entities counter and flags int ReturnFlag = 0;
// double double arrow_start_parent_angle = 0.0, arrow_end_parent_angle = 0.0, arrow_center_diff_angle = 0.0,
RotateAxisAngleAnotherTemp = 0.0, arrow_center_parent_angle_temp = 0.0, arrow_tolerance = 0.0; // set tolerance arrow_tolerance = F2dCleanUpTolerance;
// start
// compute central angle of arrow //
// angle_center = 0.5 ( angle_start + angle_end ) // atan2 returns the arctangent of y/x // atan2 returns a value in the range -pi to pi radians
// get arrow start angle F2dCleanUpLineAngle (
// input
TopVertex, StartEntity,
// output
&arrow_start_parent_angle, &RotateAxisAngleAnotherTemp) ;
34 APPENDIX D
// arrow end angle F2dCleanUpLineAngle (
// input
TopVertex, EndEntity,
// output
&arrow_end_parent_angle , SLRotateAxisAngleAnotherTemp) ; // get difference angle arrow_center_dif f_angle = f abs ( arrow_end_parent_angle arrow_start_parent_angle ) ; // same angle if ( arrow_center_dif f_angle < arrow__tolerance ) return 0 ; if ( arrow_center_dif f_angle < pi ) {
// diff < pi arrow_center_parent_angle_temp = 0. 5 ♦ ( arrow_end_parent_angle + arrow_start_parent_angle ) ; else {
// diff > pi ( take opposite angle ) arrow_center_parent_angle_temp = 0.5 ( arrow_end_parent_angle + arrow_start_parent_angle )
+ PL
// angle > 2^pi if ( fabs ( arrow_center_parent_angle_temp - 2 . 0 ♦ pi )
< arrow_tolerance ) { arrow_center__parent_angle_temp = 0.0 ; else { if ( arrow_center_parent_angle_temp > ( 2.0 pi )
{ arrow_center_parent_angle_temp = arrow center parent angle temp - 2.0 pi;
} "
) } CenterLineAngle = arrow_center_j>arent_angle_temp; // normal end return 1;
} /*
Function:
Name : F2dCleanUpFindArrowEndEntity
Description: to find arrow end line Return Value:
= 0 : No arrow;
= 1 : Arrow
35 APPENDIX D
Parameters :
Input:
1 Nodes : connected node
2 TopVertex: arrow top vertex
3 StartEntity: arrow start line entity
7 int F2dCleanUpFindArrowEndEntity(
// input struct node_list Nodes, struct planar_vertex TopVertex, struct node StartEntity )
{
// external functions int F2dCleanUpFindArrowOneSideOpenEntity() ; int F2dCleanUpComputeCenterLineAngle () ; int F2dCleanUpCheckStartEndEntity() ; int F2dCleanUpFindArrowCenterEntity() ;
// link list and temp list struct node_list temp_list;
// selected entity and temp entities struct node
Next_entity,
arrow_start_entity_parent,
arrow_end_entity,
arrow_end_entity_parent;
// entities counter and flags int assistant_line_flag = 0, ReturnFlag = 0; // double double arrow_center_parent_angle_temp = 0.0;
// start for( temp_list=Nodes; temp_list,- temp_list = temp_list->cdr) { if ( temp_list->car == NULL ) break; Next_entity = temp_list->car; arrow_end_entity = temp_list->car; // if ( Next_entity->flags != 2 ) continue; if ( Next_entity->type != CK_LINE ) continue; if ( Next_entity->line_type != StartEntity->line_type ) continue; if ( Next_entity->color != StartEntity->color ) continue; f ( Ne x t _e n t i t y - > i s_ t h i c k n e s s ! = StartEntity->is_thickness ) continue; // set parent
36 APPENDIX D arrow_start_entity_parent = StartEntity->parent, arrow_end_entity_parent = Next_entity->parent; // look for broken entity' s another side ReturnFlag = F2dCleanUpFindArrowOneSideOpenEntity( arrow_end_entity_parent->children ) ; if ( ReturnFlag == 0 ) continue; // check parents entities ReturnFlag = F2dCleanUpCheckStartEndEntity(
// input arrow_start_entity_parent, arrow_end_entity_parent
) ; if ( ReturnFlag == 0 ) continue;
// look for central entity of arrow
ReturnFlag = F2dCleanUpComputeCenterLineAngle (
// input
TopVertex, arrow_start_entity_parent , arrow_end_entity_parent ,
// output
&arrow_center_parent_angle__temp ) ; if ( ReturnFlag == 0 ) continue; // get central entity of arrow assistant_line_flag = F2dCleanUpFindArrowCenterEntity(
// input
Nodes, TopVertex, StartEntity, arrow_end_entity,
&arrow_center_parent_angle_temp ) ; return assistant line flag;
} return assistant_line_flag;
} /*
Function:
Name : F2dCleanUpChangeChildrenFlag
Description:
It is a function for changing entity's children flags.
Return Value:
= 0: Completed successfully; Parameters:
Input :
*/ int F2dCleanUpChangeChildrenFlag(struct node Entity)
// temp list struct node_list Temp_list;
// check all of children of the entity
37 APPENDIX D for ( Temp_list=Entity->children; Temp_list;
Temp_list = Temp_list->cdr) { // change flag to light gray Temp_list->car->flags = 3; if ( Temp_list->cdr == NULL ) break;
} return 0;
Function:
Name : F2dCleanUpLineLength
Description:
It is a function for computing line type entity's length.
Return Value :
= length; Parameters:
Input:
Entity: a parent entity
7 double F2dCleanUpLineLength(struct node Entity)
{
// defination double EntityLength=0.0; // compute entities' parent length
EntityLength = sqrt ( ( Entity->X1 - Entity->X2 ) ( Entity->X1 - Entity->X2 )
+ ( Entity->Y1 - Entity->Y2 ) Entity->Y1 - Entity->Y2 ) ); return EntityLength; }
Function:
Name : F2dCleanUpFindArrow
Description: look for arrow type entity and set flags to them. Return Value:
= 0: Completed successfully; Parameters:
Input :
1 Entities_list : a node list that will be
38 APPENDIX D checked
*/ int F2dCleanUpFindArrow( struct node_list Entities_list )
{
// external functions int F2dCleanUpLineAngle () ; int F2dCleanUpFindArrowEndEntity() ;
// link list and temp list struct node_list
temp_nodesl,
arrow_list,
temp_list; // selected entity and temp entities struct node Next_entity; struct planar_vertex top_vertex;
// entities counter and flags int bug_flag = 0,
ReturnFlag = 0, assistant_line_flag = 0; int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find Arrow Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
// Step__l : look for one side open entity // arrow start entity for ( temp_list=Entities_list; temp_list; temp_list = temp_list->cdr) { Next_entity = temp_list->car; // if ( Next_entity->flags != 2 ) continue; if ( Next_entity->type != CK_LINE ) continue; if ( Next_entity->no_connected_l == 0
SL& Next_entity->no_connected_2 < 2 ) continue; if ( Next_entity->no_connected_l < 2
&& Next_entity->no_connected_2 == 0 ) continue; // select entity's side if ( Next_entity->no_connected_l == 0 ) { // clear bug_flag bug_flag = 0;
// look for broken entity's another side for( arrow_list = Next_entity->parent->children;
39 APPENDIX D arrow_list; arrow_list = arrow_list->cdr) {
// ckeck another side vertex's pointer if ( Next_entity->parent->vertex2 == arrow__list->car->vertex2 ) { bug_flag = 1; break;
} if ( arrow list->cdr == NULL ) break;
} if ( bug_flag == 1 ) ( top_vertex = Next_entity->parent->vertex2 ; t e m p _ n o d e s l = arrow__list->car->connected_nodes_2 ;
else (
// clear bug_flag bug_flag = 0;
// look for broken entity's another side for( arrow_list = Next_entity->parent->children; arrow_list; arrow_list = arrow_list->cdr) ( // ckeck another side vertex's pointer if ( Next_entity->parent->vertexl == arrow_list->car->vertexl ) ( bug_flag = 1; break;
} if ( arrow_list->cdr == NULL ) break; if ( bug_flag == 1 ) { top_vertex = Next_entity->parent->vertexl ; t e m p _ n o d e s l arrow list->car->connected nodes 1;
if ( bug_flag != 1 ) continue;
// get end entity of arrow
ReturnFlag = F2dCleanUpFindArrowEndEntity(
// input temp_nodesl, top_vertex, Next_entity ) ; if ( ReturnFlag == 1 ) assistant_line_flag = 1; if ( temp_list->cdr == NULL ) break;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished find arrows Entity %d", CountPrompt ) ;
40 APPENDIX D ck_prompt ( message ) ; #endif return assistant line_flag;
} /*
Function:
Name : F2dCleanUpFindOneSideOpenEntity
Description: look for one side open entities and they are vertical with arrow type entities. Return Value:
= 0: Completed successfully and No found;
= NUM: Open entities' number Parameters:
Input :
1 Entities_list: a node list that will be checked
* / int F2dCleanUpFindOneSideOpenEntity ( struct node_list
♦Entities list )
{
// external functions int F2dCleanUpChangeChildrenFlag() ; // link list and temp list struct node_list temp_list; // selected entity and temp entities struct node Next_entity; // entities counter and flags int count = 0; // double double assistant_line_angle = 0.0, arrow_tolerance = 0.0; int CountPrompt = 0; char message [64] ;
// set tolerance arrow_tolerance = F2dCleanUpTolerance;
ttifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find One side open Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
41 APPENDIX D
// check all of entities which connected with outside loop for ( temp_list=Entities_list; temp_list; temp_list = temp_list->cdr) { if ( temp_list->car == NULL ) break; Next_entity = temp_list->car; // check flags // if ( Next_entity->flags 1 =2 ) continue; // check vertex' flag if ( Next_entity->vertexl->flags != 3
&& Next_entity->vertex2->flags != 3 ) continue; // check lines vertically if ( Next_entity->vertexl->flags == 3 ) { assistant_line_angle = fabs (
( Next_entity->X1 - Next_entity->X2 )
( Next_entity->vertexl->ArrowCenterLine_Xl
-Next_entity->vertexl->ArrowCenterLine_X2
)
+ ( Next_entity->Y1 - Next_entity->Y2 )
( Next_entity->vertexl->ArrowCenterLine_Yl
-Next_entity->vertexl->ArrowCenterLine_Y2
else { assistant_line_angle = fabs (
( Next_entity->X1 - Next_entity->X2 )
( Next_entity->vertex2->ArrowCenterLine_Xl
-Next_entity->vertex2->ArrowCenterLine_X2
+ ( Next_entity->Y1 - Next_entity->Y2 )
( Next_entity->vertex2->ArrowCenterLine_Yl
-Next_entity->vertex2->ArrowCenterLine_Y2
) ;
}
// check the angle for central entity if ( sqrt (assistant_line_angle) > arrow_tolerance ) continue;
// look for children
F2dCleanUpChangeChildrenFlag( Next_entity->parent ) ; count++;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished find one side open Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
42 APPENDIX D
// normal end return count;
Function:
Name : F2dCleanUpFindOneSideOpenEntity2
Description: look for one side open and across with views' boundaries entities after found views Return Value:
= 0: Completed successfully and No found; = NUM: Open entities' number Parameters :
Input :
1 In_drawing: drawing __ int F2dCleanUpFindOneSideOpenEntity2 ( struct drawing In_drawing )
{
// external functions int F2dCleanUpChangeChildrenFlag() ; // link list and temp list struct node_list temp_list, ConnectedNode; // selected entity and temp entities struct node Entity; // define flag int BoundaryFlag = 0; int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "2 Start Find Oneside Open Entity %d", CountPrompt ) ; ck_prompt ( message ) ; #endif
// check node list if ( In_drawing == NULL ) return -1; if ( In_drawing->objects == NULL ) return -1; // check all of entities which connected with outside loop for ( Entity=In drawing->objects;Entity;Entity = Entity->next
) {
// check connected nodes count if ( Entity == NULL ) break; if (( Entity->no_connected_l == 0 )
43 APPENDIX D
&&( Entity->no_connected_2 == 0 ) ) continue; // check flags if (( Entity->flags == 3 ) Sc&( Entity->type == CK_LINE ) && ( ( Entity->no_connected_l == 0 ) j j ( Entity->no_connected_2 == 0 ) ) ) { // one side open and line type if ( Entity->no_connected_2 == 0 )
ConnectedNode = Entity->connected_nodes_l; else ConnectedNode = Entity->connected_nodes_2; // clear found boundary's flag BoundaryFlag = 0;
// check across with views' boundary if ( ConnectedNode != NULL ) { for ( temp_list = ConnectedNode; temp_list; temp_list = temp_list->cdr ) { // check wrong data if ( temp_list->car == NULL ) break; if ( temp_list->car->flags == 4 ) { // find boundary's entity BoundaryFlag = 1; break;
} if ( temp_list->cdr == NULL ) break; if ( BoundaryFlag == 1 ) // look for children F2dCleanUpChangeChildrenFlag( Entity->parent
// check arc if (( Entity->type == CK_ARC ) &&( Entity->flags != 99 ) &&( ( Entity->no_connected_l == 0 ) I j ( Entity->no_connected_2 == 0 ) ) ) { // look for children F2dCleanUpChangeChildrenFlag( Entity->parent ) ; if ( Entity->next == NULL ) break;
}
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished 2 one side open Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
// normal end return 0; }
44 APPENDIX D
Function:
Name : F2dCleanUpFindGroupMinX
Description: look for minimum X-value for a entities group Return Value :
= 0: Completed successfully and no entity; Parameters :
Input :
1 Entities_list : a node list that will be checked
Output
1 Entity: entity includes minimum X-value
_____ struct node F2dCleanUpFindGroupMinX( struct node_list ♦Entities list )
{
// double F2dCleanUpLineLength() ;
// entities counter and flags int open_entity_flag = 0;
// link list and temp list struct node_list
EntitiesList2,
Out_temp_list2,
open_temp_list2, open_list2,
temp_listl,
temp_list2; // selected entity and temp entities struct node
Next_entity,
MinXvalueEntity; // length and angle double MinXvalueGroup = 0.0; // check all of entities which connected with outside loop // initialize EntitiesList2 =
( struct node_list ) calloc ( 1, sizeof ( struct node_list ) ) ; open_list2 =
( struct node_list ) calloc ( 1, sizeof ( struct node_list ) ) ;
// check first entity
// search connected entity until real entity be found for ( temp_list2 = Entities_list;
// entity->connected_nodes;
45 APPENDIX D
; ;
Figure imgf000315_0001
//
// Step_6_l:
// find connected entities for ( temp_listl = open_list2; ( temp_listl
// SS (temp_list->cdr != 0) > ; ) {
// get a pointer from open list if ( temp_listl->car == NULL ) break;
Next_entity = temp_listl->car;
// set a closed flag to the node
// Next_entity->flags = 1;
// close the node ( delete the node from open list ) open_list2 = open_list2->cdr;
// look for first connected entity whose flags=0. for ( temp_list2 = Next_entity->connected_nodes; ( temp_list2 !=0 &_ temp_list2->car!=0 ) ; temp_list2=temp_list2->cdr) { if ( temp_list2->car == NULL ) break; // if found an unmarked connected entity if ( temp_list2
&_ temp_list2->car->f lags==2 &_ MinXvalueEn t i ty- > 1 ine__t ype temp_list2 - >car- >line_type
&_ MinXvalueEntity- > color
46 APPENDIX D temp_l ist2 - >car- >color
_ _ MinXva lueEnt i t y - > i s_t hi ckne s s temp_list2 - >car- >is_thickness
) {
// check minimum X if ( temp list2->car->Min X < MinXvalueGroup
) {
// change minimum X value
MinXvalueGroup = temp_list2->car->Min_X;
MinXvalueEntity = temp list2->car;
}
// allocate memory for open list element open_temp_list2 = ( struct node_list ) calloc ( 1, sizeof ( struct node_list )) ;
// allocate memory for output node list element
0ut_temp_list2 = ( struct node_list ) calloc ( 1, sizeof ( struct node_list ));
// add this entity to the open list open_temp__list2->car = temp_list2->car; // add this entity to the output node list Out_temp_list2->car = temp_list2->car;
// set a open flag to the node open_temp_list2->car->flags = 1;
// connect to the open list open_temp_list2- cdr = open_list2; // move the pointer of open list to the top open_list2 = open_temp_list2; // connect to the output node list Out_temp_list2->cdr = EntitiesList2; // move the pointer of output node list to the top
EntitiesList2 = Out temp_list2;
} if ( temp list2->cdr == NULL ) break;
}
// assign value to the loop variable temp listl = open list2;
} return MinXvalueEntity;
} /*
Function:
Name : F2dCleanUpFindOutNextEntity
47 APPENDIX D
Description: look for connected entity with out side loop entities
Return Value:
= 0: Completed successfully; Parameters :
Input :
1 In_entity: rotate axis entity
2 In_Nodes: entity's node
3 In_Vertex: entity's vertex
4 In_Angle: entity's angle
*/ int F2dCleanUpFindOutNextEntity(
// input struct node In_entity, struct node_list In_Nodes, struct planar_vertex In_Vertex, double In_Angle )
{
// external functions int F2dCleanUpArcAngle () ; int F2dCleanUpLineAngle () ,- // link list and temp list struct node_list
temp_list,
RotateNodes,
RotateNodesTemp,
RotateNodesAnother,
RotateNodesAnotherTemp; // selected entity and temp entities struct node
Next_entity,
RotateEntity; struct planar_vertex
RotateVertex,
RotateVertexTemp,
RotateVertexAnother,
RotateVertexAnotherTemp; int RotateVertexFlag = 0,
RotateAxisEntityType = 0,
RotateAxisEntityVertexFlag = 0,
FindNextFlag = 0;
// length and angle double RotateAxisAngleAnother = 0.0,
RotateAxisAngleAnotherTemp - 0.0, RotateMinAngleTemp = 0.0, RotateDiffAngleTemp = 0.0, RotateAxisAngle = 0.0,
48 APPENDIX D
RotateAxisAngleTemp = 0.0; // set tolerance Tolerance double Tolerance = 0.0; Tolerance = F2dCleanUpTolerance;
// initialize
RotateAxisAngleAnother = In_Angle;
RotateEntity = In_entity;
RotateNodesAnother = In_Nodes;
RotateVertexAnother = In_Vertex;
// check all of entities which connected with outside loop for( ; ; ) (
// set flag for first entity on loop FindNextFlag = 0; RotateEntity->flags = 4;
RotateAxisEntityType = RotateEntity->type; if ( RotateEntity->vertexl == RotateVertexAnother ) RotateAxisEntityVertexFlag = 1; else RotateAxisEntityVertexFlag = 2; // set standard axis for first search RotateAxisAngle = RotateAxisAngleAnother; RotateMinAngleTemp = 2.0 pi; RotateNodes = RotateNodesAnother;
RotateVertex = RotateVertexAnother; // check next connected entity if ( RotateNodes == 0 ) break; // start loop process for( temp_list=RotateNodes; temp_list; temp_list = temp_list->cdr) { if ( temp_list->car == NULL ) break; Next_entity = temp_list->car; // check flags if ( Next_entity->flags == 4 ) break; if ( Next_entity->flags != 1 ) continue; switch ( Next_entity->type ) { // arc type entity case CK_ARC:
RotateVertexFlag = F2dCleanUpArcAngle ( // input
RotateVertex, Next_entity, // output
- R o t a t e A x i s A n g l e T e m p , SLRotateAxisAngleAnotherTemp) ; break ; // line type entity case CK LINE :
RotateVertexFlag = F2dCleanUpLineAngle // input RotateVertex, Next_entity ,
49 APPENDIX D
// output
- R o t a t e A x i s A n g l e T e m p , -RotateAxisAngleAnotherTemp) ; break; // wrong type entity default : break;
}
// select connected side of entity if ( RotateVertexFlag == 1 ) {
// get start->end
// set rotation vertex node
RotateNodesTemp Next_entity->connected_nodes_l;
RotateVertexTemp = Next_entity->vertexl;
// set another side vertex node
RotateNodesAnotherTemp Next_entity->connected_nodes_2;
RotateVertexAnotherTemp Next_entity->vertex2; else {
// set rotation vertex node
RotateNodesTemp = Next_entity->connected_nodes_2;
RotateVertexTemp = Next_entity->vertex2;
// set another side vertex node
RotateNodesAnotherTemp Next_entity->connected_nodes_l;
RotateVertexAnotherTemp Next entity->vertexl;
}
// compute diff angle // for change current entity RotateDiffAngleTemp = RotateAxisAngleTemp RotateAxisAngle; if ( fabs ( RotateDiffAngleTemp ) < Tolerance ) { switch( RotateAxisEntityType ) { case CK_ARC: switch( RotateAxisEntityVertexFlag
) { case 1 : RotateDiffAngleTemp = 2.0 pi; break; case 2 : RotateDiffAngleTemp =
0.0; break;
} break; case CK_LINE:
50 APPENDIX D switch( RotateVertexFlag ) ( case 1: RotateDiffAngleTemp =
0 . 0 ; break; case 2 : RotateDiffAngleTemp =
2 . 0 PL break;
} break;
}
} if ( RotateDiffAngleTemp < 0.0 ) {
RotateDiffAngleTemp = RotateDiffAngleTemp + 2.0
* Pi
} if ( fabs ( RotateDiffAngleTemp - RotateMinAngleTemp
) < Tolerance ) ( switch( Next_entity->type ) { case CK_ARC: switch( RotateEntity->type ) { case CK_ARC: switch( RotateVertexFlag
) ( case 1: // n o change break; case 2 :
RotateEntity
= Next_entity;
RotateNodes
= RotateNodesTemp;
RotateVertex
= RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother = RotateAxisAngleAnotherTemp; break;
} break; case CK_LINE: switch( RotateVertexFlag
) { case 1: // n o change break; case 2:
RotateEntity
51 APPENDIX D Next_entity;
RotateNodes
= RotateNodesTemp; RotateVertex RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother = RotateAxisAngleAnotherTemp; break;
} break;
} case CK_LINE: switch( RotateEntity->type ) { case CK_ARC: if ( RotateEntity->vertexl
== RotateVertex ) {
RotateEntity
= Next_entity;
RotateNodes
= RotateNodesTemp;
RotateVertex = RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother = RotateAxisAngleAnotherTemp;
} break;
}
} if ( RotateDiffAngleTemp < RotateMinAngleTemp
FindNextFlag = 1;
RotateMinAngleTemp = RotateDiffAngleTemp;
// set rotation entity
RotateEntity = Next_entity;
RotateNodes RotateNodesTemp;
RotateVertex = RotateVertexTemp;
RotateNodesAnother RotateNodesAnotherTemp;
RotateVertexAnother RotateVertexAnotherTemp;
52 APPENDIX D
RotateAxisAngleAnother RotateAxisAngleAnotherTemp;
// check flags
// if loop meet closed entity if ( Next__entity->flags == 4 ) break; if ( FindNextFlag == 0 ) break;
} return 0;
Function:
Name : F2dCleanUpFindOutSideLoop
Description: look for out side loop entities Return Value:
= 0: Completed successfully and No found;
= NUM: Outside entities' number Parameters:
Input:
1 Entity: entity includes the loop's minimum X-value
*/ int F2dCleanUpFindOutSideLoop ( struct node MinXvalueEntity )
{
// external functions int F2dCleanUpArcAngle () ; int F2dCleanUpLineAngle () ; int F2dCleanUpFindOutFirstEntity() ; int F2dCleanUpFindOutNextEntity() ;
// entities counter and flags int count = 0, count2 = 0, open_entity_flag = 0,
RotateVertexFlag = 0, assistant_line_flag = 0; // link list and temp list struct node_list
outside_loop_temp_list3 ,
RotateNodes,
RotateNodesTemp,
RotateNodesAnother,
RotateNodesAnotherTemp; // selected entity and temp entities
53 APPENDIX D struct node
♦Next_entity, RotateEntity; struct planar_vertex RotateVertex, ♦RotateVertexTemp, ♦RotateVertexAnother, ♦RotateVertexAnotherTemp; // length and angle double assistant_line_angle = 0.0, MinXvalueGroup = 0.0, RotateAxisAngleAnother = 0.0, RotateAxisAngleAnotherTemp = 0.0, RotateMinAngleTemp = 0.0, RotateDiffAngle = 0.0, RotateDiffAngleTemp = 0.0, RotateAxisAngle = 0.0, RotateAxisAngleTemp = 0.0; // set tolerance Tolerance double loop_tolerance = 0.00; loop_tolerance = F2dCleanUpTolerance;
// loop direction : counter-clock
// check a flag for outside loop process // if ( count2 > 0 ) { // step_7_l: find first entity for the group // set standard axis for first search RotateAxisAngle = 1.5 pi; RotateMinAngleTemp = 2.0 pi; // step_7_l_l : only one entity // check entities' angle
// arc case : special case ( no vertex on min_x ) if ( MinXvalueEntity->type == CK_ARC
&_ ( fabs ( MinXvalueEntity->Min_X MinXvalueEntity->vertexl->X ) > loop_tolerance )
_& ( fabs ( MinXvalueEntity->Min_X MinXvalueEntity->vertex2->X ) > loop_toleranee ) ) { // set rotation vertex node
RotateNodesAnother =MinXvalueEntity->connected_nodes_2; RotateVertexAnother = MinXvalueEntity->vertex2; RotateEntity = MinXvalueEntity; // get arc end-angle
// ( direction : from circle-center to end-point )
RotateAxisAngleAnotherTemp = ( MinXvalueEntity->AngEnd ) pi / 180.0;
// change angle to oppsite direction
// ( direction : from end-point to circle-center
RotateAxisAngleAnotherTemp = RotateAxisAngleAnotherTemp
54 APPENDIX D
+ pi;
// check angle if ( RotateAxisAngleAnotherTemp > ( 2.0 pi ) ) { R o t a t e Ax i s A n g l e An o t h e r T e mp = RotateAxisAngleAnotherTemp - 2.0 pi; if ( fabs ( RotateAxisAngleAnotherTemp - ( 2.0 ♦ pi ) ) < loop_tolerance ) {
RotateAxisAngleAnotherTemp = 0.0;
}
// compute tangent line angle for the arc end-angle
// ( direction : from end-point to start-point )
RotateAxisAngleAnotherTemp = RotateAxisAngleAnotherTemp + 0.5 pi;
// check angle if ( RotateAxisAngleAnotherTemp > ( 2.0 pi ) ) {
R o t a t e Ax i s An g l e An o t h e r T e mp RotateAxisAngleAnotherTemp - 2.0 pi;
} if ( fabs ( RotateAxisAngleAnotherTemp - ( 2.0 pi ) ) < loop_tolerance ) {
RotateAxisAngleAnotherTemp = 0.0;
}
// set rotation standard angle ( clock direction )
RotateAxisAngleAnother = RotateAxisAngleAnotherTemp;
} // step_7_l_2 : multiple entities around Min_x else {
// select connected side of entity if ( fabs ( MinXvalueEntity- >Min_X
MinXvalueEntity->vertexl->X ) < loop_tolerance )
// get start->end
// set rotation vertex node
RotateVertex = MinXvalueEntity->vertexl; else RotateVertex = MinXvalueEntity->vertex2 ; switch ( MinXvalueEntity->type ) {
// arc type entity case CK_ARC:
RotateVertexFlag = F2dCleanUpArcAngle (
// input
RotateVertex, MinXvalueEntity,
// output
- R o t a t e A x i s A n g l e T e m p ,
-RotateAxisAngleAnotherTemp) ; break;
// line type entity case CK_LINE:
RotateVertexFlag = F2dCleanUpLineAngle (
// input
RotateVertex, MinXvalueEntity,
55 APPENDIX D
// output - R o t a t e A x i s A n g l e T e m p ,
-RotateAxisAngleAnotherTemp) ; break ; def ault : break ;
// select connected side of entity if ( RotateVertexFlag == 1 ) (
// get start->end
// set rotation vertex node
RotateNodesTemp MinXvalueEntity->connected_nodes_l;
RotateVertexTemp = MinXvalueEntity->vertexl;
// set another side vertex node
RotateNodesAnotherTemp MinXvalueEntity->connected_nodes_2;
RotateVertexAnotherTemp MinXvalueEntity->vertex2; else {
// set rotation vertex node
RotateNodesTemp MinXvalueEntity->connected_nodes_2;
RotateVertexTemp = MinXvalueEntity->vertex2;
// set another side vertex node
RotateNodesAnotherTemp MinXvalueEntity->connected_nodes_l;
RotateVertexAnotherTemp = MinXvalueEntity->vertexl;
}
// compute diff angle // for change current entity
RotateDiffAngleTemp = RotateAxisAngleTemp RotateAxisAngle; if ( RotateDiffAngleTemp < 0.0 ) {
RotateDiffAngleTemp = RotateDiffAngleTemp + 2.0 ♦
Pi,
} if ( RotateDiffAngleTemp < RotateMinAngleTemp ) RotateMinAngleTemp = RotateDiffAngleTemp; // set rotation entity
RotateEntity = MinXvalueEntity;
RotateNodes = RotateNodesTemp;
RotateVertex = RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother
RotateAxisAngleAnotherTemp;
56 APPENDIX D
// step_7_l_3 : find next connected entity with first entity around Min_x-vertex
// check all of entities which connected with first entity if ( RotateNodes != 0 ) { for ( outside_loop_temp_list3=RotateNodes; outside__loop_temp_list3 ; o u t s i d e _ l o o p _ t e m p _ l i s t 3 outside_loop_temp_list3->cdr) { if ( outside_loop_temp_list3->car == NULL ) break ;
Next_entity = outside_loop_temp__list3 ->car ; // check flags if ( Next_entity->f lags !=1 ) continue; switch ( Next_entity->type ) { // arc type entity case CK_ARC:
R o t a t e V e r t e x F l a g F2dCleanUpArcAngle (
// input
RotateVertex, Next_entity, // output
-RotateAxisAngleTemp , -RotateAxisAngleAnotherTemp) ; break; // line type entity case CK_LINE:
R o t a t e V e r t e x F l a g F2dCleanUpLineAngle (
// input
RotateVertex, Next_entity, // output
-RotateAxisAngleTemp , -RotateAxisAngleAnotherTemp) ; break; // wrong type entity default : break;
}
// select connected side of entity if ( RotateVertexFlag == 1 ) { // get start->end // set rotation vertex node RotateNodesTemp = Next_entity->connected_nodes_l;
RotateVertexTemp = Next_entity->vertexl;
// set another side vertex node RotateNodesAnotherTemp Next_entity->connected_nodes_2;
57 APPENDIX D RotateVertexAnotherTemp
Next entity- >vertex2 ;
} else {
// set rotation vertex node
RotateNodesTemp Next_entity->connected_nodes_2;
RotateVertexTemp Next_entity->vertex2;
// set another side vertex node
RotateNodesAnotherTemp Next_entity->connected_nodes_l;
RotateVertexAnotherTemp Next entity->vertexl;
}
// compute diff angle
// for change current entity
RotateDiffAngleTemp = RotateAxisAngleTemp
RotateAxisAngle; if ( RotateDiffAngleTemp < 0.0 ) {
RotateDiffAngleTemp = RotateDiffAngleTemp + 2.0 pi;
} if ( f abs ( RotateDif fAngleTemp
RotateMinAngleTemp ) < loop_tolerance ) { switch { Next_entity- >type ) { case CK_ARC : switch ( RotateEntity- >type ) case CK_ARC : s w i t c h RotateVertexFlag ) { case 1 : // change break ; case 2 :
RotateEntity = Next_entity;
RotateNodes = RotateNodesTemp;
RotateVertex = RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother = RotateAxisAngleAnotherTemp; break;
}
58 APPENDIX D break; case CK_LINE: s w i t c h (
RotateVertexFlag ) { case 1: // D change break; case 2 :
RotateEntity - Next_entity;
RotateNodes = RotateNodesTemp;
RotateVertex = RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother - RotateAxisAngleAnotherTemp; break;
} break;
} case CK_LINE: switch( RotateEntity->type ) { case CK_ARC: i f (
RotateEntity->vertexl === RotateVertex ) {
RotateEntity = Next_entity;
RotateNodes = RotateNodesTemp;
RotateVertex = RotateVertexTemp;
RotateNodesAnother = RotateNodesAnotherTemp;
RotateVertexAnother = RotateVertexAnotherTemp;
RotateAxisAngleAnother = RotateAxisAngleAnotherTemp;
} break;
}
} if ( RotateDiffAngleTemp < RotateMinAngleTemp
59 APPENDIX D
RotateMinAngleTemp = RotateDiffAngleTemp;
// set rotation entity
RotateEntity = Next_entity;
RotateNodes
RotateNodesTemp;
RotateVertex
RotateVertexTemp;
RotateNodesAnother
RotateNodesAnotherTemp;
RotateVertexAnother
RotateVertexAnotherTemp;
RotateAxisAngleAnother RotateAxisAngleAnotherTemp;
// step_7_2 : find next connected entity with first entity along the loop
F2dCleanUpFindOutNextEntity( // input
RotateEntity, RotateNodesAnother, RotateVertexAnother, -RotateAxisAngleAnother ) ; return 0;
}
Function:
Name : TestFindArrowControl
Description:
It is a manual function.
To look for all arrow type entities for the view.
Return Value :
< 0 : Error = 0 : No proccess
> 0: Completed successfully; the Number is the counter of found entities. Parameters: Subfunctions : struct node_list F2dCleanUpPickUpAllOneSideOpenEntity look for one side open entity int F2dCleanUpFindArrow look for arrow type entity
60 APPENDIX D int F2dCleanUpFindArrowEndEntity find arrow end line int F2dCleanUpFindArrowCenterEntity find arrow center line int F2dCleanUpFindArrowOneSideOpenEntity find one side open entity for arrow type int F2dCleanUpComputeCenterLineAngle compute center line angle int F2dCleanUpCheckStartEndEntity check start and end entities int F2dCleanUpLineAngle compute a line type entity's angle int F2dCleanUpArcAngle compute a arc type entity's angle, int F2dCleanUpChangeChildrenFlag change entity's children flags int F2dCleanUpChangeArrowVertexFlag change arrow top vertex's flags and set arrow center line coordinates int F2dCleanUpChangeDrawingColor change entity's color double F2dCleanUpLineLength compute line type entity's length
int TestFinciArrowControl ( int ♦SwitchRedraw )
{
// external functions int F2dCleanUpFindArrow() ; int F2dCleanUpChangeDrawingColor() ; struct node_list F2dCleanUpPickUpAll0neSide0penEntity() ;
// entities counter and flags int count = 0, assistant_line_flag = 0; // link list and temp list struct node__list
Entities_change_color_listl;
// Begin
//
// Step_l:
// check the number of entites // get count of all entities // if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
//
// Step_3 : pickup all one side open entities
E n t i t i e s _ c h a n g e _ c o l o r _ l i s t l
61 APPENDIX D
F2dCleanUpPickUpAllOneSideOpenEntity( &trim_drawing ) ; if (Entities_change_color_listl == 0) return 0; /
// Step_4 : find arrow line
F2dCleanUpFindArrow( Entities_change_color_listl ) ;
// Step_X:
// change color to Magenta for a selected boundary
// turn off input levels #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels (CK_OFF, 1,255) ;
#endif if ( ♦SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ;
// clear a flag for outside loop process assistant_line_flag = 0;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_l eve l s ( CK_ON , Tr imLeve l ,
TrimLevel ) ; if ( ♦SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return count;
} /*
Function:
Name : TestFindOneSideOpen2Control
Description:
It is a manual function.
To find all one side open and across with views' boundaries entities Return Value :
< 0 : Error = 0 : No proccess Parameters: Subfunctions: int F2dCleanUpFindOneSideOpenEntity2 look for all one side open and across with views' boundaries entities int F2dCleanUpChangeDrawingColor change entity' s color -- =================_______
int TestFindOneSideOpen2Control ( int ♦SwitchRedraw )
62 APPENDIX D
{
// external functions int F2dCleanUpFindOneSideOpenEntity2 () ; int F2dCleanUpChangeDrawingColor () ;
// Step_l : check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
// Step_2: pickup all one side open entities
F2dCleanUpFindOneSideOpenEntity2 ( _trim_drawing ) ;
// Step_X: change color to Magenta for a selected boundary
// turn off input levels #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck__levels (CK_0FF, 1, 255) ; #endif if ( ♦SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels (CK_ON, TrimLeve1 , TrimLevel) ; if ( ♦SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return 0;
}
Function:
Name : TestFindOneSideOpenControl
Description:
It is a manual function.
To find all one side open and vertical with arrow type entities for the view.
Return Value:
< 0 : Error = 0: No proccess
> 0: Completed successfully; the Number is the counter of found entities. Parameters: Subfunctions : struct node_list F2dCleanUpPickUpA110neSideOpenEntity look for one side open entity int F2dCleanUpChangeChildrenFlag change entity' s children flags
63 APPENDIX D int F2dCleanUpChangeDrawingColor change entity' s color int F2dCleanUpFindOneSideOpenEntity look for one side open entities and they are vertical with arrow type entities
* / int TestFindOneSideOpenControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpFindOneSideOpenEntity() ; int F2dCleanUpChangeDrawingColor() ; struct node_list ♦F2dCleanUpPickUpAllOneSideOpenEntity() ;
// entities counter and flags int count = 0, assistant_line_flag = 0; // link list and temp list struct node_list
Entities_list;
// Begin
//
// Step_l :
// check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
//
// Step_2 : pickup all one side open entities
Entities_list = F2dCleanUpPickUpAllOneSideOpenEntity (
_trim_drawing ) ; if (Entities_list == 0) return 0; //
// Step_3 : find lines vertical with arrow type entities
F2dCleanUpFindOneSideOpenEntity( Entities list ) ; //
// Step_X:
// change color to Magenta for a selected boundary
// turn off input levels #ifdef CKWIN if ( SwitchRedraw == 1 ) ck levels (CK OFF, 1,255) ; #endif if ( SwitchRedraw == l ) F2dCleanUpChangeDrawingColor(_trim_j_rawing) ;
// clear a flag for outside loop process assistant_line_flag = 0;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels (CK_ON, TrimLevel ,
64 APPENDIX D
TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return count;
} /*
Function:
Name : F2dCleanUpPickUpAllOneSideOpenEntity
Description: look for all one side open entities in selected drawing Return Value:
= 0: Completed successfully; Parameters :
Input :
In_drawing: drawing Output:
NodeList: a node list for all one side open entities __ struct node_list ♦F2dCleanUpPickUpAllOneSideOpenEntity(struct drawing In_drawing )
{
// entities counter and flags int count = 0;
// link list and temp list struct node_list
EntitiesListl,
♦Out_temp_list; // selected entity and temp entities struct node entity;
// initialize
EntitiesListl = ( struct node list ) calloc ( 1, sizeof ( struct node list
) )
// set a flag for the boundary entity count = 0;
// check pointer about first entity if ( In_drawing->objects == 0 ) return 0; // set a open flag to the node // open_list->car->flags = 1; // set the pointer to output node list // set pointer to first entity for (entity=In_drawing->objects; entity __ (count<number_trimmed_entities) ;
65 APPENDIX D entity=entity->next) { if ( entity == NULL ) break; if ( entity->no_connected_l > 0 &_ entity->no_connected_2
> 0 ) continue; i f ( ent i t y - > no_c onne c t e d_l = = 0 Sc ¬ ent ity- >no_connected_2 == 0 ) continue ; if ( entity->type != CK_LINE ) continue; EntitiesListl->car = entity; break;
}
// set link address
EntitiesListl->cdr = NULL; /
// find connected entities if ( EntitiesListl == 0 ) return 0; if ( entity == 0 ) return 0; if ( entity->next == 0 ) return EntitiesListl; for (entity-entity->next; entity &_ (count<number_trimmed_entities) ; entity=entity->next) { count++; if ( entity == NULL ) break; if ( entity->type != CK_LINE ) continue; if ( entity->no_connected__l > 0 _SL entity->no_connected_2
> 0 ) continue; i f ( ent i ty - >no_conne c t e d_l = = 0 _ _ entity- >no_connected_2 == 0 ) continue ;
// allocate memory for output node list element
Out_temp_list = ( struct node_list ) calloc ( 1, sizeof ( struct node_list ) ) ;
// add this entity to the output node list
Out_temp_list->car = entity;
// connect to the output node list
Out_temp_list->cdr = EntitiesListl;
// move the pointer of output node list to the top
EntitiesListl = Out_temp_list; if ( entity->next == NULL ) break;
} if (co_nt>=number_trimmed_entities) return 0; else return EntitiesListl;
Function:
Name : F2dCleanUpPickUpAllArcEntity
Description: look for all arc entities in selected drawing
66 APPENDIX D
Return Value:
= 0: Completed successfully; Parameters :
Input :
In_drawing: drawing Output:
NodeList : a node list for all arc entities
Figure imgf000336_0001
// link list and temp list struct node_list
♦EntitiesListl,
♦Out_temp_list; // selected entity and temp entities struct node entity;
// initialize
EntitiesListl = ( struct node_list ) calloc ( 1, sizeof ( struct node_list
> ) ;
// set a flag for the boundary entity count = 0;
// check pointer about first entity if ( In_drawing->objects == 0 ) return 0; // set pointer to first entity for (entity=In_drawing->objects; entity __ (count<number_trimmed_entities) ; entity=entity->next) { if ( entity == NULL ) break; if ( entity->type != CK_ARC ) continue; EntitiesListl->car = entity; break;
}
// set link address
EntitiesListl->cdr = NULL; //
// find connected entities if ( EntitiesListl == 0 ) return 0; if ( entity == 0 ) return 0; if ( entity->next == 0 ) return EntitiesListl; for (entity-entity->next; entity _S_ (count<number_trimmed_entities) ; entity=entity->next) { count++; if ( entity == NULL ) break;
67 APPENDIX D if ( entity->type != CK_ARC ) continue;
// allocate memory for output node list element Out_temp_list = ( struct node_list ) calloc ( 1, sizeof ( struct node_list ) ) ;
// add this entity to the output node list
Out_temp_list->car = entity;
// connect to the output node list
Out_temp_list->cdr = EntitiesListl;
// move the pointer of output node list to the top
EntitiesListl = Out_temp_list; if ( entity->next == NULL ) break;
} if (count>=number_trimmed_entities) return 0; else return EntitiesListl;
Function:
Name : F2dCleanUpFindCenterLineEntity
Description: look for arc's center line entities. Return Value:
= 0: Completed successfully and No found; = NUM: Open entities' number Subfunctions : int F2dCleanUpChangeChildrenFlag set flags for unuse entities double F2dDistancePointLine compute distance from arc's center point to entity Parameters:
Input:
1 In_Drawing: a drawings
2 In_Entities_list: a node list for all arcs __ int F2dCleanUpFindCenterLineEntity( struct drawing ♦In_drawing, struct node list ^In Entities list )
{ "
// external functions int F2dCleanUpChangeChildrenFlag() ; double F2dDistancePointLine () ; double F2dCleanUpLineLength() ; // link list and temp list struct node_list temp_list, temp_list2, ♦temp_list3, ♦temp_list ; // selected entity and temp entities
68 APPENDIX D struct node
ArcEntity, ♦ViewEntity; // define 3D coordinates struct Vector Vsp, Vep, Vp; // entities counter and flags int count = 0; // double double Distance = 0.0,
DistanceViewEntity2Center = 0.0, DX = 0.0, DY = 0.0,
ViewEntityLength = 0.0, Tolerance = 0.0; int CountPrompt = 0 ; char message [64] ;
// set tolerance
Tolerance = F2dCleanUpTolerance;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find Center Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
// check all of entities which connected with outside loop for( temp_list=In_Entities_list; temp_list; temp_list = temp_list->cdr) { if ( temp_list->car == NULL ) break; ArcEntity = temp_list->car; // check all of entities in the view for( ViewEntity=In_drawing->objects; ViewEntity;
ViewEntity = ViewEntity->next) { // check flags : only no marks entities if ( ViewEntity->flags !=0
__ ViewEntity->flags !=10 ) continue; // check type : only line if ( ViewEntity->type != CK_LINE ) continue; // check open side : only open line if ( ViewEntity->no_connected_l > 0
_Sc ViewEntity->no_connected 2 > 0 ) continue,
// check open side : two side open line ( delete ) if ( ViewEntity->no_connected_l == 0
__ ViewEntity->no_connected_2 == 0
69 APPENDIX D
Sc- ViewEntity->line__type != CK_CENTER ) { ViewEntity->flags = 3; continue;
// check parent open side if ViewEntity->no_connected_l == 0
_6c ViewEntity->line_type != CK_CENTER ) {
// set center line flags ( look for children for ( temp_list2=ViewEntity->parent->children; temp_list2 __ temp_list2->cdr; temp_list2 = temp_list2->cdr) { // change flag to light gray if ( temp_list2->car == NULL ) break; if ( temp_list2->car->vertex2
ViewEntity->parent->vertex2 ) break; if ( temp_list2->car->no_connected_2 != 0) continue;
} if ( ViewEntity->no_connected_2 == 0
_Sc ViewEntity->line_type != CK_CENTER ) {
// set center line flags ( look for children for( temp_list3=ViewEntity->parent->children; temp_list3 _Sc temp_list3->cdr; temp_list3 = temp_list3->cdr) { // change flag to light gray if ( temp_list3->car == NULL ) break; if ( temp_list3->car->vertexl
== ViewEntity->parent->vertexl ) break;
} if ( temp_list3->car->no_connected_l != 0) continue;
} // check distance from arc's center to line entity
Vsp.x=ViewEntity->X1;Vsp.y=ViewEntity->Y1;Vsp. z=ViewEntity->Z1;
Figure imgf000339_0001
70 APPENDIX D
Sc& ( ViewEntity->parent- >Max_Y > =
ArcEntity- >Min_Y
__ ViewEntity- >parent - >Max_Y < =
ArcEntity- >Max_Y )) {
F 2 dC l e anUpChange Ch i l dre nF l ag ( ViewEntity- >parent ) ; continue;
} if (( ViewEntity- >parent - >Min_X >= ArcEntity- >Min_X
ScSc ViewEntity- >parent - >Min_X < =
ArcEntity- >Max_X )
_δc ( ViewEntity- >parent - >Min_Y > =
ArcEntity- >Min_Y
_δc ViewEntity- >parent- >Min_Y < =
ArcEntity- >Max_Y )) {
F 2 dC l e anUp Change Ch i l dren F l ag ( ViewEntity- >parent ) ; continue;
} if (( ArcEntity->Max_X >= ViewEntity->parent->Min_X
Sc _ A r c E n t i t y - > M a x _ X < =
ViewEntity->parent->Max_X )
SC SL ( A r c E n t i t y - > M a x _ Y > =
ViewEntity- >parent - >Min_Y
Sc _ Ar c En t i t y - > Ma x_Y < =
ViewEntity- >parent->Max_Y ) ) {
F 2 dC l e anUpChange Ch i l dre nF l ag ( ViewEntity- >parent ) ; continue;
} if (( ArcEntity- >Min_X >= ViewEntity- >parent->Min_X
_ 5c A r c E n t i t y - > M i n _ X < =
ViewEntity- >par ent ->Max_X )
_ SL ( A r c E n t i t y - > M i n_Y > =
ViewEntity- >parent - >Min_Y
Sc _ ArcEnt i ty - >M in_Y < =
ViewEntity- >parent - >Max_Y ) ) {
F 2 dCle anUpChangeChi ldrenF l ag (
ViewEntity- >parent ) ; continue;
}
// check distance from arc to entity
V i e w E n t i t y L e n g t h F2dCleanUpLineLength (ViewEntity- >parent) ;
D X =
0.5* (ViewEntity- >parent->Min_X+ViewEntity->parent->Max_X)
- ArcEntity->CenterX;
D Y
0.5* (ViewEntity->parent->Min_Y+ViewEntity->parent->Max_Y)
- ArcEntity->CenterY;
71 APPENDIX D
DistanceViewEntity2Center = sqrt (DX+DX+DY^DY)
- ArcEntity->Radius - 0.5♦ViewEntityLength; if ( DistanceViewEntity2Center <= ViewEntityLength
F 2 dC l e anUp Change Chi l drenF l ag ( ViewEntity- >parent ) ; continue;
// set center line flags ( look for children ) for ( temp_list4=ViewEntity->parent->children; temp_list4; temp_list4 = temp_list4->cdr) ( // change flag to light gray if ( temp_list4->car == NULL ) break; temp_list4->car->flags = 10; count++;
} if ( ViewEntity->next == NULL ) break;
} }
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished find center Entity %d", CountPrompt ) ; ck_prompt ( message ) ; #endif
// normal end return count;
} /*
Function:
Name : F2dCleanUpFindInSideEntity
Description: look for in side entities for outside loop. Return Value :
= 0: Completed successfully and No found;
= NUM: Open entities' number Subfunctions: int F2dCleanUpChangeChildrenFlag set flags for unuse entities Parameters:
Input :
1 In_Drawing: a drawings
2 In_Entities_list : a node list for outside loop
72 APPENDIX D
*/ int F2dCleanUpFindInSideEntity( struct drawing In_drawing, struct node_list In_Entities_list )
{
// external functions int F2dCleanUpChangeChildrenFlag() ;
// link list and temp list struct node_list
♦temp_list, temp_list2,
♦NewNodeList, NewNodeListTemp; struct group
NewGroup,
♦temp_group_list; struct bounding_box NewBoundBox; // selected entity and temp entities struct node
OutsideEntity,
ViewEntity; // entities counter and flags int count = 0,
NoFlag = 0; // double double Tolerance = 0.0;
// set tolerance
Tolerance = F2dCleanUpTolerance;
// initialize
NewGroup = (struct group ) calloc (1, sizeof (struct group )) ; NewBoundBox = (struct bounding_box ) calloc (1, sizeof (struct bounding_box ) ) ;
NewNodeList = (struct node_list )calloc (1, sizeof (struct node_list ) ) ;
// set group data NewGroup->next = NULL; NewGroup->box = NewBoundBox;
// check all of entities which connected with outside loop for ( temp_list=In_Entities_list; temp_list; // __ temp_list->cdr; temp_list = temp__list->cdr) { if ( temp__list->car == NULL ) break; OutsideEntity = temp_list->car; // check entity : only boundary group ( flags = 1 and
4 ) if ( OutsideEntity->flags != 1
_Sc OutsideEntity->flags != 4 ) continue; if ( !OutsideEntity ) {
NoFlag = 1; break;
}
73 APPENDIX D
NewGroup->box->Min_X = OutsideEntity->Min_X
NewGroup->box->Max_X = OutsideEntity->Max_X
NewGroup->box->Min_Y = OutsideEntity->Min_Y
NewGroup->box->Max_Y = OutsideEntity->Max_Y break;
} if ( NoFlag == 1 ) return 0;
NewNodeList->car = OutsideEntity;
NewNodeList->cdr = NULL;
// check first group if ( In_drawing->views == NULL ) {
NewGroup->index = 1;
In drawing->views = NewGroup;
} else {
// check group number for( temp_group_list= In drawing->views; temp_group_list; 7/ && temp_group_list->next; temp_group_list = temp_group_list->next) { if ( temp_group_list->next == NULL ) {
NewGroup->index = (temp_group_list->index) +1; temp_gro_p_list->next = NewGroup; break;
}
}
}
// check connected entity if ( !temp_list->cdr __ temp_list->car->type != CK_ARC ) return 0;
// check all of entities which connected with outside loop if ( temp_list->cdr ) { for ( temp_list2 = temp_list->cdr; temp_list2; // __ temp_list2->cdr; temp_list2 = temp_list2->cdr) { if ( temp_list2->car == NULL ) break; OutsideEntity = temp_list2->car; // check entity : only boundary group ( flags = 1 and 4 ) if ( OutsideEntity->flags != 1
_Sc OutsideEntity->flags != 4 ) continue if ( NewGroup->box->Min_X > OutsideEntity->Min_X )
NewGroup->box->Min_X = OutsideEntity->Min_X if ( NewGroup->box->Max_X < OutsideEntity->Max_X
NewGroup->box->Max_X = OutsideEntity->Max_X if ( NewGroup->box->Min_Y > OutsideEntity->Min_Y )
NewGroup->box->Min_Y = OutsideEntity->Min~Y if ( NewGroup->box->Max_Y < OutsideEntity->Max~Y )
NewGroup->box->Max_Y = OutsideEntity->Max_Y // allocate memory for node list NewNodeListTemp = (struct node_list
74 APPENDIX D
♦) calloc (1, sizeof (struct node_list )) ;
// add this entity to node list NewNodeListTemp->car = OutsideEntity; // connect to the node list NewNodeListTemp->cdr - NewNodeList; // move the pointer of the node list to the top NewNodeList = NewNodeListTemp; count++; }
}
// check all of entities in the view for ( ViewEntity=In_drawing->objects; ViewEntity;
ViewEntity = ViewEntity->next) { // check flags : only no marks entities if ( ViewEntity == NULL ) break; if ( ViewEntity->flags !=0 ) continue; // check bounding box: only inside entities if ( ( NewGroup->box->Min_X <= ViewEntity->Min_X ) __( NewGroup->box->Max_X >= ViewEntity->Max_X ) Sc_( NewGroup->box->Min_Y <= ViewEntity->Min_Y ) __( NewGroup->box->Max_Y >= ViewEntity->Max_Y )) // set flag ViewEntity->flags = 7; // allocate memory for node list
NewNodeListTemp = (struct node_list ♦) calloc (1, sizeof (struct node_list )) ;
// add this entity to node list NewNodeListTemp->car = ViewEntity; // connect to the node list NewNodeListTemp->cdr = NewNodeList; // move the pointer of the node list to the top NewNodeList = NewNodeListTemp; count++,- }
}
// set node list to group
NewGroup->entities = NewNodeList;
// normal end return count;
Function:
Name : F2dCleanUpFindOnesideOpenConnectEntityNext
Description: look for next entity connected with one side open entity
75 APPENDIX D
Return Value:
= Out_entity: Completed successfully; Parameters :
Input :
1 In_entity: entity
s *truct node ♦F2dCleanUpFindOnesideOpenConnectEntityNext (struct node
♦In entity)
{
// selected entity and temp entities struct node ♦Out_entity;
// link list and temp list struct node_list
TempListl, TempList2, TempList3, NextNodes;
// define int Flagl = 0,
Flag2 = 0,
Count = 0; int CountPrompt = 0; char message [64] ;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find One Side Open Connected Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
// initialize Out_entity = NULL;
// check input entity if ( !In_entity ) return Out_entity;
// check open side for( TempListl=In_entity->connected_nodes_l;
TempListl; // ScSc TempListl->cdr;
TempListl = TempListl->cdr) { if ( TempListl->car == NULL ) break; if ( TempListl->car->flags == 6 ) Flagl = 1; for ( TempList2=In_entity->connected_nodes_2 ; TempList2; // __ TempList2->cdr; TempList2 = TempList2->cdr) { if ( TempList2->car == NULL ) break; if ( TempList2->car->flags == 6 ) Flag2 = 1;
// first entity case if ( Flagl == 0 __ Flag2 == 0 ) {
76 APPENDIX D if ( In_entity->no_connected_l == 0 ) Flagl = 1; if ( In entity->no_connected_2 == 0 ) Flag2 = 1;
}
// f inish case : return if ( ( Flagl == 0 __ Flag2 == 0 ) j I ( Flagl == 1 &&. Flag2 == 1 ) ) return Out_entity;
// check all of entities connected with input entity if ( Flagl == 1 ) NextNodes = In_ent ity- >connected_nodes_2 ; else N e x t N o d e s
In_entity- >connected_nodes_l ; for ( TempList3= NextNodes;
TempList3; // SL TempList3->cdr; TempList3 = TempList3->cdr) { if ( TempList3->car == NULL ) break; if ( TempList3->car->flags == 0 ) { Out_entity = TempList3->car; Count++; }
}
// check result if ( Count != 1 ) Out_entity = NULL;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished one side open connected Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif return Out entity;
} /*
Function:
Name : F2dCleanUpFindOnesideOpenConnectEntity
Description: look for one side open entity and single connected with it Return Value:
= 0: Completed successfully; Subf nctions: struct node F2dCleanUpFind0neside0penConnectEntityNext look for next entity connected with one side open entity Parameters :
Input :
1 In_drawing: drawing
77 APPENDIX D int F2dCleanUpFindOnesideOpenConnectEntity(struct drawing ♦In drawing)
{
// external functions struct node ♦F2dCleanUpFindOnesideOpenConnectEntityNext () ;
// selected entity and temp entities struct node ♦entity, FindEntity, NextEntity;
// check all of entities on the list for( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity == NULL ) break; if ( entity->flags != 0 ) continue; if ( entity->type != CK_LINE ) continue; if ( entity->no_connected_l > 0
__ entity->no_connected_2 > 0 ) continue; if ( entity->no_connected_l == 0
__ entity- >no_connected_2 == 0 ) continue; if ( ( en t i t y - >no_c onne c t ed_l == 0 &.& entity- >no_connected_2 >= 1)
I I (entity- >no_connected_2 == 0 __ entity- >no_connected_l >= 1) ) {
// set flag entity->flags = 6; FindEntity = entity; // find connected entity for (;;) {
NextEntity =
F2dCleanUpFindOnesideOpenConnectEntityNext ( FindEntity ) ; if ( NextEntity == NULL ) break; // set flag FindEntity = NextEntity; FindEntity->flags = 6;
return 0;
Function:
Name : F2dCleanUpFindLongestEntity
Description: look for a longest entity for a drawing Return Value :
78 APPENDIX D
- Entity: Completed successfully; 0 : No entity; Parameters:
Input:
1 In_drawing: drawing
s *7tr "uct node F2dCleanUpFindLongestEntity(struct drawing ♦In drawing)
{ "
// selected entity and temp entities struct node entity, LongestEntity;
// define double LongestLength = 0.0,
ArcLength = 0.0;
// check all of entities on the list for( entity=In_drawing->objects; entity; entity = entity->next) ( // only not used if ( entity == NULL ) break; if ( entity->flags != 0 ) continue; // check length if ( entity->parent->length <= LongestLength ) continue;
// check arc length if ( entity->type == CK_ARC ) {
ArcLength = 2.0 entity->parent->Radius; if ( entity->parent->length < ArcLength )
ArcLength = entity->parent->length; if ( ArcLength > LongestLength ) { // change max value and entity LongestLength = ArcLength; LongestEntity - entity;
else {
// change max value and entity LongestLength = entity->parent->length; LongestEntity = entity;
if ( LongestLength == 0.0 ) return NULL; else return LongestEntity;
/*
79 APPENDIX D
Function:
Name : F2dCleanUpFindViews
Description: look for view's groups for a drawing Return Value:
Entity: Completed successfully; 0 : No entity; Subfunctions : struct node ♦F2dCleanUpFindLongestEntity look for a longest entity for a drawing struct node_list F2dCleanUpFindGroup look for a group entities connected with input entity struct node ♦F2dCleanUpFindGroupMinX look for minimum X-value for a entities group int F2dCleanUpFindOutSideLoop look for out side loop entities int F2dCleanUpFindInSideEntity look for in side entities for outside loop Parameters :
Input:
1 In_drawing: drawing
*/~~ int F2dCleanUpFindViews ( struct drawing +In drawing )
{
// external functions struct node F2dCleanUpFindLongestEntity() ; struct node_list F2dCleanUpFindGroup() ; struct node F2dCleanUpFindGroupMinX() ; int F2dCleanUpFindOutSideLoop () ; int F2dCleanUpFindInSideEntity() ;
// selected entity and temp entities struct node LongestEntity, MinXvalueEntity; struct node_list ViewGroup;
// define int ReturnFlag = 1,
NoGroup = 0,
Count = 0; double LongestLength = 0.0; int CountPrompt = 0; char message [64] ;
// check all views while ( ReturnFlag ) { #ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find Views Entity %d" , CountPrompt ) ; ck_prompt ( message ) ;
80 APPENDIX D
#endif
// Step_l: find a longest entity for a drawing LongestEntity = F2dCleanUpFindLongestEntity( In_drawing ) ; if ( LongestEntity == NULL ) ReturnFlag = 0; else {
// set flag
NoGroup = 1;
// clear counter
Count = 0;
// Step_2 : find connected group with the longest entity
ViewGroup = F2dCleanUpFindGroup ( LongestEntity, -Count )
// Step_3 : find outside loop entities
// check a flag for outside loop process if ( Count > 1 ) M i n Xv a l u e E n t i t y
F2dCleanUpFindGroupMinX( ViewGroup ) ; else MinXvalueEntity = LongestEntity; if ( MinXvalueEntity == 0 ) continue;
// Step_4 : find outside loop entities if ( Count > 1 ) F2dCleanUpFind0utSideLoop (
MinXvalueEntity ) ; else MinXvalueEntity->flags = 4; // Step_5 : find inside entities F2dCleanUpFindInSideEntity( In drawing, ViewGroup ) ;
} #ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished find view Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif
} if ( NoGroup == 0 ) return -1; else return 0;
}
/*
Function:
Name : F2dCleanUpFindRelativeViews
Description: look for relative views. Return Value:
= 0: Completed successfully;
= 1 : Found relative Views Parameters:
Input :
1 In_Drawing: a drawing
81
Figure imgf000351_0001
APPENDIX D
2 In_Group: a group
3 In ToleranceViews : tolerance for views
*/ int F2dCleanUpFindRelativeViews ( struct drawing In_drawing, struct group In_Group, double ♦In_ToleranceViews )
{
// link list and temp list struct group TempGroup; struct group_list Te pGroupList; // entities counter and flags int ReturnFlag = 0; // double double Tolerance = 0.0;
// set tolerance
Tolerance = In_ToleranceViews;
// check views if ( In_drawing->views == NULL ) return 0; if( In_Group == NULL ) return 0; for ( TempGroup= In_drawing->views;
TempGroup; // _& TempGroup->next; TempGroup = TempGroup->next) { // check same group if ( TempGroup == NULL ) break; if ( TempGroup == In_Group ) continue; // Step_l: check top and bottom direction i f
( (TempGroup->box->Max_X>= ( (In_Group->box->Max_X) -Tolerance ) )
SE_(TempGroup->box->Max_X<= ( (In_Group->box->Max_X) +Tolerance ) )
__ (TempGroup->box->Min_X>= ( (In_Group->box->Min_X) -Tolerance ) )
_& (TempGroup->box->Min_X<= ( (In_Group->box->Min_X) +Tolerance ) ) ) { // set return flag ReturnFlag = 1;
// Step_l_l : check top direction if ( TempGroup->box->Min Y > In Group->box->Max Y ) { "
// check top direction relative views if ( In_Group->to_top == NULL ) {
TempGroupList = (struct group_list ) calloc (1, sizeof (struct group_list )) ;
TempGroupList->car = TempGroup; TempGroupList->cdr = NULL; In_Group->to_top - TempGroupList;
82 APPENDIX D else {
// check distance if ( In_Group->to_top->car->box->Min_Y > TempGroup->box->Min_Y ) {
// change top view In_Group->to_top->car = TempGroup;
else
// Step_l_2 : check bottom direction if ( TempGroup->box->Max Y < In Group->box->Min Y
) { "
// check top direction relative views if ( In_Group->to_bottom == NULL ) {
TempGroupList = (struct group_list ♦) calloc (1, sizeof (struct group_list ));
TempGroupList->car = TempGroup; TempGroupList->cdr = NULL; In_Group->to_bottom = TempGroupList; else {
// check distance if ( In_Group->to_bottom->car->box->Max_Y < TempGroup->box->Max_Y ) (
// change top view
In Group->to bottom->car = TempGroup;
} else
// Step_2 : check left and right direction i f
( (TempGroup->box->Max_Y>= ( (In_Group->box->Max_Y) -Tolerance ) )
__(TempGroup->box->Max_Y<= ( (In_Group->box->Max_Y) +Tolerance ) )
Figure imgf000352_0001
( (In_Group->box->Min_Y) -Tolerance ) )
_δc(TempGroup->box->Min_Y<= ( (In_Group->box->Min_Y) +Tolerance ) ) ) {
// set return flag ReturnFlag = 1;
// Step_2_l: check right direction if ( TempGroup->box->Min_X > In_Group->box->Max_X
) {
// check right direction relative views if ( In_Group->to_right == NULL ) {
TempGroupList = (struct group_list
83 APPENDIX D
♦) calloc (1, sizeof (struct group_list )) ;
TempGroupList->car = TempGroup;
TempGroupList->cdr = NULL;
In Group->to right = TempGroupList;
} else {
// check distance if ( In_Group->to_right->car->box->Min_X
> TempGroup->box->Min_X ) {
// change left view
In Group->to right->car = TempGroup;
}
}
} else
// Step_2_2 : check left direction if ( TempGroup->box->Max_X < In_Group->box->Min_X
) {
// check left direction relative views if ( In_Group->to_left == NULL ) {
TempGroupList = (struct group_list
♦) calloc (1, sizeof (struct group_list )) ;
TempGroupList->car = TempGroup;
TempGroupList->cdr = NULL;
In Group->to left = TempGroupList;
} else {
// check distance if ( In_Group->to_left->car->box->Max_X <
TempGroup->box->Max_X ) {
// change right view
In_Group->to_left->car = TempGroup;
» ' '
// normal end return ReturnFlag;
/*
Function:
Name : F2dCleanUpFindViewsRelation Description: look for views relation for a drawing. Return Value:
= 0: Completed successfully and No found;
84 APPENDIX D
= NUM: Views' number Subfunctions: int F2dCleanUpFindRelativeViews look for relative views Parameters:
Input :
1 In_Drawing: a drawings __ int F2dCleanUpFindViewsRelation( struct drawing In_drawing )
{
// external functions int F2dCleanUpFindRelativeViews 0 ;
// link list and temp list struct group
MaxGroup,
TempGroup,
NextGroup; struct group_list
♦OpenGroupList,
♦TempOpenGroupList,
♦TempGroupList; struct node_list ETL; // Entity Temp List
// entities counter and flags int NoFlag = 0;
// double double BiggestSize = 0.0,
BiggestSizeTemp = 0.0; double Tolerance = 0.0,
ToleranceViews = 0.0;
// set tolerance
Tolerance = F2dCleanUpTolerance;
// check views if ( In_drawing->views -= NULL ) return 0;
// Step_l : get the biggest group's size for ( TempGroup= In_drawing->views;
TempGroup; // ScSc TempGroup->next; TempGroup = TempGroup->next) { // clear flags TempGroup->index = 0; // compute size for box BiggestSizeTemp = fabs ( TempGroup->box->Max_X - TempGroup->box->Min_X )
+ fabs ( TempGroup->box->Max_Y - TempGroup->box->Min_Y
) ;
// check size if ( BiggestSizeTemp > BiggestSize ) { BiggestSize = BiggestSizeTemp;
85 APPENDIX D
MaxGroup = TempGroup;
}
// check last one if ( TempGroup->next == NULL ) break;
}
// check views tolerance
ToleranceViews = 0.01 BiggestSize; if ( ToleranceViews < Tolerance ) ToleranceViews = Tolerance;
// Step_2 : find relationship for each view // initialize a open list
OpenGroupList = (struct group_list ) calloc (1, sizeof (struct group_list ) ) ;
OpenGroupList->car = MaxGroup; OpenGroupList->cdr = NULL; // set a open flag to the group MaxGroup->index = 1; for ( TempGroupList = OpenGroupList; TempGroupList; ) ( // get a pointer from open list if ( TempGroupList->car == NULL ) break; NextGroup = TempGroupList->car; // set a closed flag to the group NextGroup->index = 2;
// close the group ( delete the group from open list ) OpenGroupList = OpenGroupList->cdr; // get relation
NoFlag = F2dCleanUpFindRelativeViews ( In_drawing, NextGroup, -ToleranceViews ) ; if ( NoFlag == 0 ) break;
// check each direction for the view if ( NextGroup->to_top != NULL ) { if ( NextGroup->to_top->car->index == 0 ) {
TempOpenGroupList = (struct group_list ) calloc(1, sizeof (struct group_list ));
T e m p O p e n G r o u p L i s t - > c a r NextGroup- >to_t op- >car ;
TempOpenGroupList->cdr - OpenGroupList; TempOpenGroupList->car->index = 1; OpenGroupList = TempOpenGroupList;
if ( NextGroup->to_bottorn != NULL ) { if ( NextGroup->to_bottom->car->index == 0 ) {
TempOpenGroupList = (struct group_list ) calloc (1,sizeof (struct group_list ));
T e m p O p e n G r o u p L i s t - > c a r NextGroup- >to_bottom->car ;
TempOpenGroupList->cdr = OpenGroupList; TempOpenGroupList->car->index = 1; OpenGroupList = TempOpenGroupList;
86 APPENDIX D
if ( NextGroup->to_left != NULL ) { if ( NextGroup->to_left->car->index == 0 ) {
TempOpenGroupList = (struct group_list ♦) calloc (1, sizeof (struct group_list ) ) ;
T e m p O p e n G r o u p L i s t - > c a r NextGroup- >to_lef t - >car ;
TempOpenGroupList->cdr = OpenGroupList; TempOpenGroupList->car->index = 1; OpenGroupList = TempOpenGroupList;
if ( NextGroup->to_right != NULL ) { if ( NextGroup->to_right->car->index == 0 ) {
TempOpenGroupList = (struct group_list ♦) calloc (1, sizeof (struct group_list )) ;
T e m p O p e n G r o u p L i s t - > c a r NextGroup- >to_right - >car ;
TempOpenGroupList->cdr = OpenGroupList; TempOpenGroupList->car->index = 1; OpenGroupList = TempOpenGroupList;
// assign value to the loop variable TempGroupList = OpenGroupList;
}
// Step_3 : clear flags for no relative groups for ( NextGroup=In_drawing->views; NextGroup; NextGroup NextGroup->next) { if ( NextGroup == NULL ) break; if ( NextGroup->index != 0 ) continue; for ( ETL=NextGroup->entities; ETL; ETL=ETL->cdr ) { ETL->car->flags = 0; if ( ETL->cdr == NULL ) break;
// normal end return 0;
} /*
Function:
Name : F2dCleanUpFindDrawingSheet
Description: look for drawing sheet for a drawing
87 APPENDIX D
Return Value:
= -1 : Error data;
0: Completed successfully; 1: No sheet; Subfunctions: struct node_list F2dCleanUpFindGroup look for a group entities connected with input entity
Parameters:
Input :
1 In_drawing: drawing
___ _ int F2dCleanUpFindDrawingSheet ( struct drawing In_drawing, struct bounding_box InOut_BB, int ΛIn TimesFlag )
{
// external functions struct node_list F2dCleanUpFindGroup() ;
// selected entity and temp entities struct node entity, LongestEntityX, LongestEntityY; struct node_list SheetGroup, temp_list2;
// bounding box struct bounding_box BB, EBB;
// define int SheetFlag = 0, count = 0,
CountPrompt = 0; double LongestLengthX = 0.0,
LongestLengthY = 0.0,
AlphaX = 0.0, AlphaY = 0.0; char message [64] ; double Tolerance = 0.0; // set tolerance Tolerance = F2dCleanUpTolerance;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Start Find Sheet Entity %d", CountPrompt ) ; ck__prompt ( message ) ; #endif
// STEP_1 : look for the longest line type parent entity
// check all of entities on the list for( entity=In_drawing->objects; entity;
88 APPENDIX D entity = entity->next) { // only line type if ( entity == NULL ) break; if ( entity->type != CK_LINE ) continue; // only not used if ( entity->flags != 0 ) continue; // check length if ( ( entity->parent->length <= LongestLengthX ) -S ( entity->parent->length <= LongestLengthY )) continue,
// check horizontally and vertically
// if angle (alpha) was smaller than ( sin ( alpha ) alpha )
AlphaX = fabs ( ( entity->parent->Max_X entity->parent->Min__X )
/ entity->parent->length ) ; AlphaY = fabs ( ( entity->parent->Max_Y entity->parent->Min_Y )
/ entity->parent->length ) ; if ( ( AlphaX > Tolerance ) ScSc ( AlphaY > Tolerance ) ) continue;
// change max value and entity if ( AlphaY < Tolerance ) { if ( entity->parent->length > LongestLengthX ) {
LongestLengthX = entity->parent->length; LongestEntityX = entity;
else { if ( entity->parent->length > LongestLengthY ) {
LongestLengthY = entity->parent->length; LongestEntityY = entity;
#ifdef VELLUM
//CountPrompt++;
//sprintf ( message, "Sheet Entity %d" , CountPrompt ) ;
//ck_prompt ( message ) ; #endif
}
// check the longest entitiy's length if ( ( LongestLengthX < Tolerance )
I I ( LongestLengthY < Tolerance )) return -1;
// set bounding box
BB.Min_X = LongestEntityX->parent->Min_X BB.Max_X = LongestEntityX->parent->Max_X BB.Min_Y = LongestEntityY->parent->Min_Y
89 APPENDIX D
BB.Max_Y = LongestEntityY->parent->Max_Y;
// check inside drawing sheet size if ( ♦In_TimesFlag == 1) InOut_BB = BB; // set values else { if ( (InOut_BB->Min_X =- 0.0 ) &_ (InOut_BB->Max_X == 0.0
)
__(InOut_BB->Min_Y == 0.0 ) __ (InOut_BB->Max_Y == 0.0
) ) return 0; if (( BB.Max_X - BB.Min_X ) < Tolerance ) return ξ> if ( f bs ( ( InOut_BB->Max_X - InOut_BB->Min_X ) / (
BB.Max X - BB.Min X )) > 1.2 ) return 0;
/ r/ set a flag to entity LongestEntityX->flags = 3;
// STEP_2 : look for connected entities group and make boundary
SheetGroup = F2dCleanUpFindGroup( LongestEntityX, -count ) ; if ( SheetGroup == 0 ) return 0;
// STEP_3 : clear flags for all entities for ( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity =- NULL ) break; if ( entity->flags == 3 ) continue; if ( entity->flags == 4 ) continue; entity->flags = 0;
}
// STEP_4 : set flags the group for ( temp_list2 = SheetGroup; ( temp_list2 !=0 Sc& temp_list2->car!=0 ) ; temp_list2=temp_list2->cdr) { if ( temp_list2->car == NULL ) break; temp list2->car->flags = 3;
}
// STEP_5 : set expanding box ( 20% for +X,-X,+Y,-Y )
EBB.Min_X = ( BB.Min_X ) - 0.2 fabs ( ( BB.Max_X ) - ( BB.Min_X ) ) ;
EBB.Max_X = ( BB.Max_X ) + 0.2 fabs ( ( BB.Max_X ) - ( BB.Min_X ) ) ;
EBB.Min_Y = ( BB.Min_Y ) - 0.2 fabs ( { BB.Max_Y ) - ( BB.Min_Y ) ) ;
EBB.Max_Y = ( BB.Max_Y ) + 0.2 fabs ( ( BB.Max_Y ) - ( BB.Min_Y ) ) ;
// STEP_6: check outside entity( out of the bounding box
90 APPENDIX D
) in the DRAWING
// if any entity was found, no sheet was found for this drawing for ( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity == NULL ) break; if ( entity->flags != 0 ) continue; // look for out side entity if ( entity->Max_X > EBB.Max_X ) { SheetFlag = 1; break;
} if ( entity->Max_Y > EBB.Max_Y ) {
SheetFlag = 1; break;
} if ( entity->Min_X < EBB.Min_X ) (
SheetFlag = 1; break;
} if ( entity->Min_Y < EBB.Min_Y ) {
SheetFlag = 1; break;
}
}
// STEP_7 : look for sheet data ( out side of the boundary
) if ( SheetFlag == 0 ) {
// look for sheet data for ( entity=In_drawing->objects; entity; entity = entity->next) { if ( entity == NULL ) break; if ( entity->flags == 3 ) entity->flags = 4; if ( entity->flags != 0 ) continue; if (( entity->Min_X <= BB.Min_X ) i j ( entity->Max_X
>= BB.Max_X )
! ( entity->Min_Y <= BB.Min_Y ) | | ( entity->Max_Y >= BB.Max Y ) )
// set flag entity->flags =
// Good return 0; }
// STEP_8 : clear flags ( No sheet was found ! ) for( entity=In_drawing->objects;
91 APPENDIX D entity; entity = entity->next) { if ( entity == NULL ) break; if ( entity->flags == 4 ) continue; entity->flags = 0;
} if ( SheetFlag != 0 ) return 1;
#ifdef VELLUM
CountPrompt++; sprintf ( message, "Finished find Sheet Entity %d" , CountPrompt ) ; ck_prompt ( message ) ; #endif return 0;
}
/*
Function:
Name : TestFindDrawingSheetControl
Description:
It is a manual function. To find drawing sheet for a drawing. Return Value:
< 0 : Error = 0 : No proccess
> 0: Completed successfully; the Number is the counter of found entities. Parameters: Subfunctions: int F2dCleanUpFindDrawingSheet look for drawing sheet for a drawing, int F2dCleanUpChangeDrawingFlag change entities' flags ( 4 >> 3 ) __ int TestFindDrawingSheetControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpFindDrawingSheet () ; int F2dCleanUpChangeDrawingColor() ; int F2dCleanUpChangeDrawingFlag() ;
// define struct bounding_box BB; int ReturnFlag = 0; int TimesFlag = 0;
//
92 APPENDIX D
// Step_l : check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
// Step_2 : find center line entities
TimesFlag = 1;
ReturnFlag = F2dCleanUpFindDrawingSheet ( _trim_drawing, _BB, ScTimesFlag ) ; if ( ReturnFlag == 1 ) return 0; if ( ReturnFlag == -1 ) return 0;
TimesFlag = 2;
F2dCleanUpFindDrawingSheet ( _trim_drawing, _BB, ScTimesFlag ) ; //
// Step_3 : change flags
F2dCleanUpChangeDrawingFlag( _trim_drawing ) ;
// Step_X: change color to light gray for a selected center lines
// turn off input levels #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels (CKJDFF, 1, 255) ; #endif if ( SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_ON, TrimLevel , TrimLevel) ;
//if ( SwitchRedraw == 1 ) ck_redraw ( CK_PRIME_VP ) ; #endif return 0;
} /*
Function:
Name : TestFindViewsControl
Description:
It is a manual function. To find views for a drawing. Return Value:
< 0 : Error = 0 : No proccess
> 0: Completed successfully; the Number is the counter of found entities. Parameters : Subfunctions : int F2dCleanUpFindViews
93 APPENDIX D look for view's groups for a drawing int F2dCleanUpFindViewsRelation look for views relation for a drawing int F2dCleanUpChangeDrawingColor
*/" int TestFindViewsControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpFindViews () ; int F2dCleanUpFindViewsRelation() ; int F2dCleanUpChangeDrawingColor () ;
// Step_l : check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
// Step_2 : find views' group if ( F2dCleanUpFindViews ( _trim_drawing ) == -1 ) return
-l;
// Step_3 : find views' relationship
// move to delete function ( Mar. 29,1996 ) //F2dCleanUpFindViewsRelation( _trim_drawing ) ;
// Step_X: change color to light gray for a selected center lines
// turn off input levels #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_OFF, 1, 255) ; #endif if ( SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( SwitchRedraw _= 1 ) ck_levels (CK_ON, TrimLevel , TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ,- #endif return 0;
}
Function:
Name : TestFindBoundaryControl
Description:
It is a manual function. When user selected a
94 APPENDIX D boundary' s entity of a view, the function would find all of the connected entities for the view.
Return Value:
< 0 : Error = 0 : No proccess
> 0: Completed successfully; the Number is the counter of found entities. Parameters : Subfunctions: int F2dCleanUpFind0utSideLoop look for out side loop entities int F2dCleanUpFindInSideEntity look for in side entities for outside loop int F2dCleanUpFind0utNextEntity look for connected entity with out side loop entities struct node F2dCleanUpFindGroupMinX look for minimum X-value for a entities group struct node_list F2dCleanUpFindGroup look for a group entities connected with input entity struct node F2dCleanUpInputEntity ( old function ) look for a selected entity on screen int F2dCleanUpLineAngle compute a line type entity' s angle int F2dCleanUpArcAngle compute a arc type entity's angle, int F2dCleanUpChangeChildrenFlag change entity's children flags int F2dCleanUpChangeArrowVertexFlag change arrow top vertex's flags and set arrow center line coordinates int F2dCleanUpFindViewsRelation look for views relation for a drawing int F2dCleanUpChangeColor change entity's color double F2dCleanUpLineLength compute line type entity's length __
int TestFindBoundaryControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpChangeDrawingColor() ; int F2dCleanUpFind0utSideLoop () ;
95 APPENDIX D int F2dCleanUpFindInSideEntity() ; int F2dCleanUpFindViewsRelation () ; struct node ♦F2dCleanUpInputEntity() ; struct node ♦F2dCleanUpFindGroupMinX() ; struct node_list F2dCleanUpFindGroup() ;
// entities counter and flags int count = 0;
// link list and temp list struct node_list Entities_list;
// selected entity and temp entities struct node
entity,
MinXvalueEntity;
// Begin
//
// Step_l:
// check the number of entites // get count of all entities // if an error occurred, exit immidiately. if (number_of_entities<0) return -1; for( ; ; ) { //
// Step_2 : select one entity entity = F2dCleanUpInputEntity( "Select a Boundary Entity for a view",
_trim_drawing) ; if ( entity == 0 ) return 0; if ( entity->flags != 0 ) continue;
//
// Step_3 : find a connected entities group
Entities list = F2dCleanUpFindGroup( entity, -count ); //
// Step_4 : find outside loop entities without assistant entities
// check a flag for outside loop process if ( count < 1 ) continue;
MinXvalueEntity = F2dCleanUpFindGroupMinX (
Entities_list) ; if ( MinXvalueEntity == 0 ) continue; //
// Step_5 : find outside loop entities
F2dCleanUpFindOutSideLoop( MinXvalueEntity ) ; //
// Step_6 : find inside entities
F2dCleanUpFindInSideEntity( _trim_drawing, Entities list
);
//
96 APPENDIX D
// Step_7 : find views' relationship
// move delete function (Mar.29, 1996 By Ji )
//F2dCleanUpFindViewsRelation( _trim_drawing ) ; /
// Step_X: change color to Magenta for a selected boundary
// turn off input levels #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_OFF, 1, 255) ; #endif
F2dCleanUpChangeDrawingColor(Sctrim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_leveIs (CK_ON,TrimLevel, TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif
} return count;
}
/*
Function:
Name : TestFindCenterLmeControl
Description:
It is a manual function.
To find center line for all arcs in the view. Return Value:
< 0: Error = 0 : No proccess
> 0: Completed successfully; the Number is the counter of found entities. Parameters : Subfunctions : struct node_list F2dCleanUpPickUpAllArcEntity look for all arc entities in selected drawing int F2dCleanUpChangeDrawingColor change entity's color __
int TestFindCenterLmeControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpFindCenterLineEntity() ; int F2dCleanUpChangeDrawingColor() ; struct node_list ♦F2dCleanUpPickUpAllArcEntity() ;
97 APPENDIX D
// link list and temp list struct node_list
♦Entities_list;
// Begin
// Step_l: check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
// Step_2: pickup all arc entities
Entities_list = F2dCleanUpPickUpAllArcEntity( _trim_drawing ) ; if (Entities_list == 0) return 0; /
// Step_3 : find center line entities
F2dCleanUpFindCenterLineEntity( _trim_drawing, Entities_list
) ;
//
// Step_X: change color to light gray for a selected center lines
// turn off input levels #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_OFF, 1, 255) ; #endif if ( SwitchRedraw -= 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_leve l s ( CK_ON , TrimLeve l ,
TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return 0; }
/ *
Function:
Name : TestFindOneSideOpenConnectControl
Description:
It is a manual function.
To find one side open connected entities. Return Value:
< 0 : Error
= 0: No proccess
> 0: Completed successfully; the Number is the counter of found entities.
98 APPENDIX D
Parameters: Subfunctions : int F2dCleanUpFindOnesideOpenConnectEntity look for one side open connected entities. ____ int TestFindOneSideOpenConnectControl { int SwitchRedraw )
{
// external functions int F2dCleanUpFindOnesideOpenConnectEntity() ; int F2dCleanUpChangeDrawingColor() ;
/
// Step_l : check the number of entites
// if an error occurred, exit immidiately. if (number_of_entities<0) return -1; /
// Step_2 : find center line entities
F2dCleanUpFindOnesideOpenConnectEntity( Setrim_drawing ) ; //
// Step_X: change color to light gray for a selected center lines
// turn off input levels #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels (CK_OFF, 1, 255) ; #endif if ( SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor (_trim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels ( CK_ON, TrimLevel , TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return 0;
}
/ *
Function:
Name : TestFindSameColorControl
Description:
It is a manual function.
To find same color entities.
Return Value:
= 0: Completed successfully; the Number is the counter of
99 APPENDIX D found entities. Parameters: Subfunctions: struct node F2dCleanUpInputEntity ( old function ) look for a selected entity on screen int F2dCleanUpFindSameColorEntity look for same color entities by a selected entity int F2dCleanUpChangeDrawingColor change entity's color
* / int TestFindSameColorControl ()
{
// external functions int F2dCleanUpChangeDrawingColor() ; int F2dCleanUpFindSameColorEntity() ; struct node F2dCleanUpInputEntity() ;
// selected entity and temp entities struct node entity;
// Begin
//
// Step_l:
// check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1; for( ; ; ) { //
// Step_2 : select one entity entity = F2dCleanUpInputEntity( "Select a Unuse Color Entity",
_trim_drawing) ; if ( entity == 0 ) return 0; if ( entity->flags != 0 ) continue;
//
// Step_3 : find a connected entities group
F2dCleanUpFindSameColorEntity( entity, Sctrim drawing ) ; //
// Step_X: change color to Magenta for a selected boundary
// turn off input levels #ifdef CKWIN ck_levels(CK_OFF, 1,255) ; #endif
F2dCleanUpChangeDrawingColor(_trim_drawing) ; // turn ON the level used to store the trimmed entities. #ifdef CKWIN ck_levels (CK_ON,TrimLevel, TrimLevel) ;
100 APPENDIX D if ( SwitchRedraw == 1 ) ck_redra ( CK_PRIME_VP ) ; #endif
} return 0;
}
/ *
Function:
Name : TestFindSelectSingleControl
Description:
It is a manual function. To find a use entity.
Return Value :
= 0: Completed successfully; Parameters: Subfunctions : struct node F2dCleanUpInputEntity ( old function ) look for a selected entity on screen __ int TestFindSelectSingleControl ()
{
// external functions struct node F2dCleanUpInputEntity() ;
// selected entity and temp entities struct node entity;
// entity' s specifitys
CK_ENTATT attr; // specificity of entities
// Begin
//
// Step_l: check the number of entites // if an error occurred, exit immidiately. if (number_of_entities<0) return -1; for( ; ; ) { //
// Step_2: select one entity entity = F2dCleanUpInputEntity( "Select an Unuse Entity", _trim_drawing) ; if ( entity == 0 ) return 0; //
// Step_3 : change flag if ( entity->flags == 7 ) { entity->flags = 0; attr.color = CK BLUE;
} else if ( entity->flags == 0 ) {
101 APPENDIX D entity->flags = 7; attr.color = CK YELLOW;
} else return 0; /
// Step_X: change color to light gray for unuse entity
// turn off input levels // ck_levels(CK_OFF, 1,255) ; ck_setattr( entity->id, CK_COLOR, NULL, _attr ) ;
// turn ON the level used to store the trimmed entities, // ck_leveIs (CK_ON,TrimLevel, TrimLevel) ; ck redraw( CK PRIME VP ) ;
} " return 0;
} /*
Function:
Name : TestUnselectSingleControl
Description:
It is a manual function. To clear an unuse entity. Return Value:
= 0: Completed successfully; Parameters: Subf nctions: struct node F2dCleanUpInputEntity ( old function ) look for a selected entity on screen
int TestUnselectSingleControl ()
// external functions struct node F2dCleanUpInputEntity() ;
// selected entity and temp entities struct node entity;
// entity's specifitys
CKJ3NTATT attr; // specificity of entities
// Begin
//
// Step_l : check the number of entites // if an error occurred, exit immidiately. if (number of entities<0) return -1; for(
//-
102 APPENDIX D
// Step_2 : select one entity entity = F2dCleanUpInputEn ity( "Select an Entity to release" ,
_trim_drawing) ; if ( entity -= 0 ) return 0;
// Step_3 : change flag if ( entity->flags != 3 __ entity->flags != 4 cSc entity->flags != 10 ) continue; entity->flags = 0;
// Step X: change color to light gray for unuse entity 7/ turn off input levels ck_levels(CK_OFF, 1,255) ; attr.color = entity->color; ck_setattr( entity->id, CK_COLOR, NULL, _attr );
// turn ON the level used to store the trimmed entities. ck_levels (CK_ON,TrimLevel, TrimLevel) ; ck redra ( CK PRIME VP ) ;
} return 0;
Function:
Name : TestClearKeepFlagsControl
Description:
It is a manual function.
To return all selected entities to back
Return Value:
= 0: Completed successfully;
Parameters: Subfunctions: int F2dCleanUpClearDrawingKeepFlags change entity's color to back but keep flags _____
int TestClearKeepFlagsControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpClearDrawingKeepFlags () ;
// Begin
//
103 APPENDIX D
// check the number of entites
// if an error occurred, exit immidiately. if (number_of_entities<0) return -1;
// turn off input levels
#ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_0FF, 1,255) ; #endif
F2dCleanUpClearDrawingKeepFlags (_trim_drawing) ; if ( SwitchRedraw == 1 ) ck_redra ( CK_PRIME_VP );
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_0N, TrimLevel , TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return 0; }
*
Function:
Name : TestClearControl
Description:
It is a manual function.
To return all selected entities to back
Return Value:
= 0: Completed successfully;
Parameters: Subfunctions: int F2dCleanUpClearDrawingEntity change entity's color to back __
int TestClearControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpClearDrawingEntity() ;
// Begin
//
// check the number of entites
// if an error occurred, exit immidiately.
104 _
APPENDIX D if (number_of_entities<0) return -1; /
// turn off input levels #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels(CK_OFF,1,255) ; #endif
F2dCleanUpClearDrawingEntity(Sctrim_drawing) ;
// turn ON the level used to store the trimmed entities. #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_ON, TrimLevel , TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redraw( CK_PRIME_VP ) ; #endif return 0; }
/ *
Function:
Name : TestDeleteControl
Description:
It is a manual function. To delete all selected entities.
Return Value:
= 0: Completed successfully;
Parameters: Subfunctions: int F2dCleanUpDeleteDrawingEntity delete selected entity
*/ int TestDeleteControl( int SwitchRedraw )
{
// external functions int F2dCleanUpDeleteDrawingEntity() ;
// Begin
//
// check the number of entites
// if an error occurred, exit immidiately. if (number_of_entities<0) return -1; // Step_7: find views' relationship
// move from find boundary function (Mar.29, 1996 By Ji
105 APPENDIX D
F2dCleanUpFindViewsRelation( Sctrim_drawing );
#ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_OFF, 1,255) ; #endif
// turn ON the level used to store the trimmed entities.
F2dCleanUpDeleteDrawingEntity(_trim_drawing) ; #ifdef VELLUM if ( SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ; #endif #ifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_ON, TrimLevel , TrimLevel) ; if ( SwitchRedraw == 1 ) ck_redra ( CK_PRIME_VP ); #endif return 0; }
*
Function:
Name : TestBackColorControl
Description:
To undo. Return Value:
= 0 : Completed successfully; Parameters : Subfunctions : int F2dCleanUpUndo undo
*/ int TestBackColorControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpChangeDrawingColor() ; if ( SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(Sctrim_drawing) ; return 0; }
/*
Function:
106 APPENDIX D
Name : TestUndoControl Description:
To undo. Return Value :
= 0: Completed successfully; Parameters : Subfunctions: int F2dCleanUpUndo undo
*/ int TestUndoControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpUndo() ;
// check the number of entites : if an error occurred, exit immidiately. if (number_of_entities<0) return -1; // Step_l: get flags if ( F2dCleanUpUndo ( _trim_drawing ) == 0 ) return 0; ttifdef CKWIN if ( SwitchRedraw == 1 ) ck_levels (CK_OFF, 1, 255) ; #endif
// turn ON the level used to store the trimmed entities. #ifdef VELLUM if ( SwitchRedraw == 1 ) F2dCleanUpChangeDrawingColor(_trim_drawing) ; #endif #ifdef CKWIN if ( ♦SwitchRedraw == 1 ) ck_levels (CK_ON, TrimLevel , TrimLevel) ; if ( ♦SwitchRedraw == 1 ) ck_redra ( CK_PRIME_VP ); #endif return 0; }
/*
Function:
Name : TestUndoPreControl
Description:
To prepare undo. Return Value:
= 0: Completed successfully; Parameters: Subfunctions : int F2dCleanUpUndoPre
107 APPENDIX D to prepare undo
*/ int TestUndoPreControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpUndoPre () ;
// check the number of entites: if an error occurred, exit immidiately. if (number_of_entities<0) return -1; // Step_l: get flags
F2dCleanUpUndoPre ( _trim_drawing ) ; return 0;
} /*
Function:
Name : TestSetUndoFlagViewsControl
Description:
To set a flag for undo. flag=0: views are not exist flag=l : views are exist. Return Value:
= 0: Completed successfully; Parameters:
'/ int TestSetUndoFlagViewsControl ( int SwitchRedraw )
// set flag F2dCleanUpExcutedNo = 1; return 0;
}
/'
Function:
Name : TestDeleteViewsControl
Description:
To delete views. Return Value:
= 0: Completed successfully; Parameters:
108 APPENDIX D
Subfunctions: int F2dCleanUpDeleteViews to delete views __—
int TestDeleteViewsControl ( int SwitchRedraw )
{
// external functions int F2dCleanUpDeleteViews () ;
// check the number of entites: if an error occurred, exit immidiately. if (number_of_entities<0) return -1; // delete views
F2dCleanUpDeleteViews ( _trim_drawing ) ; return 0; } struct node ♦F2dCleanUpInputEntity(char prompt, struct drawing ♦select drawing)
{ int etype, count, stat; unsigned long entid; struct node ♦entity;
// CK_ENTATT attr; if (( ck_getent (prompt, _etype, _entid) != CK_N0ERR0R) I ( stat == CK_BACKUP ) j ( stat == CK_ESCAPE )) return 0;
#ifdef DEBUG printC'ID: %ld; #",entid);
#endif count=0; for (entity=select_drawing->objects; entity St_ (count<number_trimmed_entities) 6c_ (entity->id !=entid) &_ (entity->highlighted_id !=entid) ; entity=entity->next) count++; if (count>=number_trimmed_entities) return 0; else return entity;
} /*
Function:
109 APPENDIX D
Name : F2dVector
Description:
To compute line's unit vector.
Return Value :
- Out_v: Completed successfully;
Parameters:
Input :
1 In_sp: line entity start point coordinates
2 In_ep: line entity end point coordinates Output :
1 Out_v: line entity vector
*7 struct Vector F2dVector( struct Vector In_sp, struct Vector In_ep
)
{ struct Vector Out_v;
Out_v.x - In_ep.x - In_sp.x; Out_v.y = In_ep.y - In_sp.y; Out_v.z = In_ep.z - In_sp.z; return Out v; }
*
Function:
Name : F2dVectorUnit
Description:
To compute line's unit vector.
Return Value:
- Out_n: Completed successfully; < 0 : Error. Parameters:
Input :
1 In_v: line entity vector Output:
1 Out_n: line entity unit vector __
struct Vector F2dVectorUnit ( struct Vector In_v)
110 APPENDIX D
struct Vector Out_n; double Length = 0.0;
// tolerance double tolerance = 0.0; tolerance = F2dCleanUpTolerance;
Length = sqrt( In_v.x^In_v.x + In_v.y^In_v.y + In_v.zΛIn_v.z
// check length if ( Length < tolerance ) return Out n;
Out_n.x = In_v.x / Length Out_n.y - In_v.y / Length Out n.z = In_v.z / Length return Out n;
*
Function:
Name : F2dDistancePointLine
Description:
To compute distance from a point to a line.
Return Value:
= 0: Completed successfully;
Parameters:
Input:
1 In_sp: line entity start point coordinates
2 In_ep: line entity end point coordinates
3 In_p: point coordinates. Output:
1 Out_d: distance __
double F2dDistancePointLine(
// input struct Vector In_sp, struct Vector In_ep, struct Vector In_p
)
{
// external functions struct Vector F2dVector(); struct Vector F2dVectorUnit () ;
// define
111 APPENDIX D struct Vector Ve, Vne, Vp; double Out_d=0.0;
// get vector
Ve = F2dVector( In_sp, In_ep ) ;
Vp = F2dVector( In_sp, In_p ) ;
// get unit vector
Vne = F2dVectorUnit ( Ve ) ;
// compute distance
Out_d = sqrt ( Vp.x+Vp.x + Vp.y^Vp.y
-(Vp.x^Vne.x + Vp.y+Vne.y) (Vp.x^Vne.x + Vp.y^Vne.y) ) ,- return Out d;
112 APPENDIX E iiiinmiiiiiii in 117 ii II i nu 'iiiiiin 'illinium
II II
1/ Example of bend model viewer implementation; contains // // implementation of CBendCADViewPart member functions, // // and implementation of menu-driven functions. //
// //
// Copyright 1996 AmadaSoft America, Inc. //
// //
////////////////////////////////////////////////////////////////// #include "stdafx.h"
// include all BMAPI files #include "ALLBMAPI .HXX"
// RW_DRAW library include file. #include "RW_DRAW.HXX"
#include "BendCAD.h" #include "BendCADDoc.h" #include "BendCADViewPart .h"
// RenderWare include files; found in \rwwin\include #include "rwlib.h"
// OpenGL include files. #include "gl\gl.h" #include "gl\glu.h"
// GL_LIST library include file. #include "GL_LIST.HXX"
#include <stdlib.h>
// Orthoview dialog include file #include "OrthoViewDlg.h"
minium
#define WINDOWTITLE "BAJA CAD SYSTEM" static void multiply_pt_by__matrix(BM_POINT point, float rot_matrix[4] [4] ) ; static RwClump RWCALLBACK do__transformations (RwClump ♦clump, void
matrix) ,- static RwClump RWCALLBACK clear_scene (RwClump ♦clump) ; static RwPolygon3d RWCALLBACK SetPolygonColor (RwPolygon3d
polygon, void color) ;
// The following variables are defined to set up the color palette
1 APPENDIX E of the screen. unsigned char threetoδ [8] =
0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
unsigned char twotoθ [4] = 0, 0x55, Oxaa, Oxff
unsigned char onetoθ [2] = 0, 255
static int defaultOverride [13] =
0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
static PALETTEENTRY defaultPalEntry[20] =
Figure imgf000383_0001
192, 220, 192, 0
166, 202, 240, 0
255, 251, 240, 0
160, 160, 164, 0
Figure imgf000383_0002
void PrintString(char s) APPENDIX E
}
// This function initializes the RenderWare library, creates a scene, camera and light. int CBendCADViewPart: :Init3D(HWND window)
{
BOOL berr = FALSE;
// Open the RenderWare library, if ( IRwOpen("MSWindows" , NULL) )
{
: :MessageBox(window,
"Could not open the RenderWare library",
WINDOWTITLE, MB_OK | MB_ICONSTOP |
MB_APPLMODAL) ; return 0; '
}
// Create a camera.
Rwlnt32 x_size, y_size; x_size = GetSystemMetrics(SM_CXFULLSCREEN) ; // The camera should be able to display y_size = GetSystemMetrics (SM_CYFULLSCREEN) ; // on the maximum size allowed by the screen. m_camera = RwCreateCamera (x_size, y_size, NULL) ; if ( ! m camera)
{
: :MessageBox(window, "Could not create camera",
WINDOWTITLE, MB_OK | MB_ICONSTOP j
MB_APPLMODAL) ; return 0; else {
RwSetCameraProjection(m_camera, rwPARALLEL) ;
RwWCMoveCamera(m_camera, O.Of, O.Of, 10000.Of) ;
// Move camera far away from xy plane. RwSetCameraViewport (m__camera, 0, 0, x_size, y_size) ;
// Default sizes of viewing volume RwSetCameraViewwindow (m_camera , (float) (x_size) , (float) (y size)) ; // and viewport.
} "
// Create a scene. m_scene = RwCreateScene () ; if (m scene == NULL)
{
RwDestroyCamera (m_camera) ; m_camera = NULL; RwClose () ; APPENDIX E
: :MessageBox(window, "Could not create the 3D Scene",
WINDOWTITLE, MB_OK j MB_IC0NST0P | MB_APPLMODAL) ; return 0;
}
Figure imgf000385_0001
berr = TRUE; if (light2)
{ m_lights.Add(light2) ; RwAddLightToScene (m_scene, light2) ,- else berr = TRUE; if (light3)
{ m_lights.Add(light3) ,- RwAddLightToScene (m_scene, light3) ; else berr = TRUE; if (berr) AfxMessageBoxCCould not create light source") ;
//RwSetLightState(m_light, rwON) ;
//RwSetLightColor (m_light, CREAL (1.0) , CREAL (1.0) , CREAL(1.0)) ; return 1; }
// This function is used by the document class to initialize certain APPENDIX E
// parameters whenever a new part is loaded. What we do here is compute the centroid,
// prepare RenderWare clumps and show the part as requested - wireframe/shaded if show_solid is 0/1,
// flat/3d version of part if show_3d is 0/1. void CBendCADViewPart: :new_part_init (int show_solid, int show_3d)
{ int i;
BM_PART ^part = NULL;
CBendCADDoc^ pDoc = GetDocument () ;
ASSERT_VALID(pDoc) ; part = pDoc->get_part () ,- if(! part) { mi_part_is__up_to_date = 0; return;
} mi_jpart_is_up_to_date = 1; compute_part_centroid(part, 0, _m_flat_part_centroid) ; / /
Compute 3d and flat part centroids . - compute_part_centroid(part, 1, _m_3d_part_centroid) ; m_part_centroid = m_3d_part_centroid; mi_show_3d = show_3d; mi_show_solid = show_solid;
// Clear out any RenderWare clumps around, if (m_flat_base_clump) {
RwRemoveClumpFromScene (m_flat_base_clump) ;
RwDestroyClump(m_flat_base_clump) ; m flat base clump - NULL; i }f ("m_3d_~base_"clump) {
RwRemoveClumpFromScene (m_3d_base_clump) ;
RwDestroyClump(m_3d_base_clump) ; m 3d base clump = NULL;
} " " " m_base_clump = NULL; if (mi_show_3d) { // Prepare
3d solid or 3d wireframe. m_part_centroid - m_3d_part_centroid; if ( ! mi_show_solid) { // Prepare wireframe . i = prepare_display__list (part, mi_show_3d, 1, 0, 1, 1, md_face_color, md_bendline_color) ; if(! i) { mi_display_list_is_up_to_date = 0; return; } APPENDIX E
Figure imgf000387_0001
w re rame. i = prepare_display_list (part, mi_show_3d, 1, 0, 1, 1, md_face_color, md_bendline_color) ; if(! i) { mi_display_list_is_up_to_date = 0; return;
} mi_display_list_is_up_to_date = 1; mi_flat_is_up_to_date = 1; mi_3d_is_up_to_date = 0; else { //
Prepare solid. i - facet_part_rw(part, _m_flat_base_clump, mi_show_3d, md_part_color) ; i ( (! i) M (! m_flat_base_clump) ) return; m_base_clump = m_flat_base_clump; RwAddClumpToScene (m_scene, m_base_clump) ; mi_display_list_is_up_to_date = 0; mi_3d_is_up_to_date = 0; mi_flat_is_up_to_date = 0;
mi_bbox_is_up_to_date = 0; ml_num_faces = part->get_number_of_faces () ; ml_num_bendlines = part->get_number_of_bendlines 0 ; ml_n_m_formings = part->get_number_of_formings() ; clear_selection_set () ; reset_selection bufferO ; APPENDIX E OnViewIsometric ( ) ,-
}
// This function destroys all parent clumps in the scene, and hence all clumps in the scene.
// It always returns NULL. static RwClump ♦ RWCALLBACK clear_scene(RwClump ♦clump) int i = RwGetClumpNumChildren(clump) ,- if(i) RwDestroyClump(clump) ; return NULL; }
// This allows other classes to signal that the part has changed, and hence
// current clumps/display lists are no longer valid. We recompute centroids, prepare new clumps
// or display lists, and show the part in its current orientation and zoom. void CBendCADViewPart::invalidate display(void)
{ int i;
BM_PART ^part = NULL;
CBendCADDoc^ pDoc = GetDocument() ;
ASSERT_VALID(pDoc) ; part = pDoc->get_part() ; if(! part) { mi_part_is_up_to_date - 0; return;
} mi__part_is_up_to_date = 1; compute_part_centroid(part, 0, _m_flat_part_centroid) ; / / Compute 3d and flat part centroids. compute_part_centroid(part, 1, _m_3d_part_centroid) ; mi_3d_is_up_to_date = 0; mi_flat_is_up_to_date - 0;
// Clear out any RenderWare clumps around, if (m_flat_base_clump) {
RwRemoveClumpFromScene(m_flat_base__clump) ;
RwDestroyClump(m_flat_base_clump) ; m flat base clump = NULL; i }f("m_3d_"base_"cl_mp) {
RwRemoveClumpFromScene (m_3d_base_clump) ; APPENDIX E
RwDestroyClump(m_3d_base_clump) ; m 3d__base_clump = NULL; m }_base__clump = NULL; if (mi_show_3d) { // Prepare 3d solid or 3d wireframe. m_part_centroid = m_3d_part_centroid; if ( ! mi_show_solid) ( // Prepare wireframe . i = prepare_display_list (part, mi_show_3d, 1, 0, 1, 1, md face_color, md_bendline_color) ; if(! i) { mi_display_list_is_up_to_date = 0; return;
} mi_display_list_is_up_to_date = 1; mi_3d_is_up_to_date = 1; mi_flat_is_up_to_date = 0;
} , else ( //
Prepare solid. i = facet_part_rw(part, _m_3d_base_clump, mi show 3d, md_part_color) ; if ( (! i) | | (! m_3d_base_clump) ) return; m_base_clump = m_3d_base_clump;
RwAddClumpToScene (m_scene, m_base_clump) ;
} else { // Prepare flat solid or flat wireframe. m_part_centroid = m_flat_part_centroid; if ( ! mi_show_solid) { // Prepare wireframe. i = prepare_display_list (part, mi_show_3d, 1, 0, 1, 1, md_face_color, md_bendline color) ; if(! i) { mi_display_list_is__p_to_date = 0; return;
} mi_display_list_is_up_to_date = 1; mi_flat_is_up_to_date = 1; mi_3d_is_up_to_date = 0; else { //
Prepare solid. i = facet_part_rw(part, _m_flat_base_clump, mi show 3d, md_part_color) ; ~ if( (! i) | J (! m_flat_base_clump) ) return; m_base_clump = m_flat_base_clump; APPENDIX E RwAddClumpToScene (m_scene, m_base_clump) ;
} } mi_bbox_is_up_to_date = 0; ml_num_faces = part->get_number_of_faces() ; ml_num_bendlines = part->get_number_of_bendlines () ; ml_num_formings = part->get_number_of_formings () ; clear_selection_set () ; reset_selection_buf er () ; ml_last_function_chosen = RETURN_FROM_DIALOG_MODE;
DrawPart (m_hdc) ; ml last function chosen = NO FUNCTION MODE;
void CBendCADViewPart: :OnShowFlat () { if ( 1 mi_show_3d) return; // Flat is already being shown. int i;
BM_PART part = NULL;
CBendCADDoc^ pDoc = GetDocument () ;
ASSERT_VALID(pDoc) ; part = pDoc->get_part () ,- if(! part) { mi_part_is_up_to_date = 0; return;
}
// Store the current 3d view parameters. md_old_x_trans = md_x_trans; md_old_y_trans = md_y trans; for(i=0; i < 3; ++i) J md_old__part_bbox_size [i] = md_part_bbox_size [i] ; md old view vol [i] = md current view vol [i] ;
} " " - " " " if (md_old__rot_matrix) RwDestroyMatrix(md_old_rot_matrix) ; md_old_rot_matrix = RwDuplicateMatri (md_rot_matrix) ; mi_show_3d = 0; m_part_centroid = m_flat_part__centroid; if ( ! mi_show_solid) ( // Compute the flat's display list. if ( ! mi_flat_is_up_to_date) { i = prepare_display_list (part, mi_show_3d, 1, 0, 1, 1, md face color, md bendline color) ; APPENDIX E if(! i) { mi_display_list_is_up_to_date = 0; return;
}
} mi_display_list_is_up_to_date = 1; mi_flat_is_up_to_date = 1; mi_3d_is_up_to_date = 0; else { // Compute flat's clump if not already done. if (m_3d_base_clump) RwRemoveClumpFromScene (m_3d_base_clump) ; m_base_clump = NULL; if ( ! m_flat_base_clump) { i = facet_part_rw(part, _m_flat_base_clump, mi_show_3d, md_part_color) ; if( (! i) | | (! m_flat_base_clump) ) { mi_display_list_is_up_to_date = 0; return;
' » m_base_clump = m_flat_base_clump; // Set the base clump to be the flat's base clump. } RwAddClumpToScene (m-scene, m-base-clump) ;
mi_bbox_is_up_to_date = 0; OnViewTop () ;
// Here we show the 3d version, in its old orientation and zoom
(before flat was
// asked to be shown) . void CBendCADViewPart : :0nShow3d()
{ if (mi_show_3d) return; // 3D view is already being shown. int i;
BM_PART part = NULL;
CBendCADDoc^ pDoc = GetDocument () ;
ASSERT_VALID(pDoc) ; part = pDoc->get_part () ; if(i part) { mi_part_is_up_to_date = 0; return;
}
10 APPENDIX E
// Restore the old 3d view parameters. md_x_trans = md_old_x_trans; md_y_trans = md_old_y trans; for(i=0; i < 3; ++i) md_part_bbox_size [i] = md_old_part_bbox_size [i] ; md_current_view_vol [i] = md_old_view_vol [i] ; if (md_rot_matrix) RwDestroyMatrix(md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix(md_old_rot_matrix) ; mi_show_3d = 1; _part_centroid = m_3d_part_centroid; if ( ! mi_show_solid) { if ( ! mi_3d_is_up_to_date) { i = prepare_display_list (part, mi_show_3d, 1, 0, 1, 1, md_face_color, md_bendline_color) ; if(! i) { mi_display_list_is_up_to_date = 0; return;
} mi_display_list_is_up_to_date = 1; mi_3d_is_up_to_date = 1; mi_flat_is_up__to_date = 0;
else { // Compute the 3d_version's clumps if have not already done so. i f ( m _ f l a t _ b a s e _ c l u m p ) RwRemoveClumpFromScene (m_flat_base_clump) ; m_base_clump = NULL; if ( ! m_3d_base_clump) { i = facet_part_rw(part, _m_3d_base_clump, mi_show_3d, md_part_color) ; if( (! i) | | (! m_3d_base_clump) ) ( mi_display_list_is_up_to_date = 0; return;
) ' m_base_clump = m_3d_base_clump; // Set the base clump to be the 3d version's base clump.
RwAddClumpToScene (m_scene, m_base_clump) ;
mi_bbox__is__up_to_date = 0; md_current_view_vol [1] = md_current_view_vol [0] /md_aspect;
RwSetCameraViewwindo (m_camera, (float) (md_current_view_vol [0] ) , (float) (md current view vol [1] ) ) ;
11 APPENDIX E glMatrixMode (GL_PROJECTION) ; glLoadldentity() ; glOrtho(- md_current_view_vol [0] , md_current_view_vol [0] , md_current_view_vol [ 1 ] , md_current_view_vol [1] , // - 50000.0, 50000.0) ;
- md_current_view_vol [2] , md_current_view_vol [2] ) ; glMatrixMode (GL_MODELVIEW) ;
DrawPart (m hdc) ;
void CBendCADViewPart: :OnHide3d()
{
OnShowFlat () ; // For now, just switch to showing flat. }
void CBendCADViewPart : :OnHideFlat ()
{
OnShow3d(); // For now, just switch to showing
3D.
}
void CBendCADViewPart: :OnViewWireframe ()
{ if ( ! mi_show_solid) return; // Wireframe already being shown, int i;
CreateRGBPalette(m_hdc) ; // when wireframe -- recreate the palette -- AK
HGLRC hrc - wglGetCurrentContext {) ; // The rendering context of OpenGL. wglMakeCurrent (NULL, NULL) ; wglMakeCurrent (m_hdc, hrc) ; // Associate the rendering context with this view.
BM_PART ^part = NULL; CBendCADDoc^ pDoc = GetDocument () ; ASSERT_VALID(pDoc) ; part = pDoc->get_part () ; if(! part) { mi_part_is_up_to_date = 0; return;
}
12 APPENDIX E mi_show_solid = 0;
Figure imgf000394_0001
ml_last_function_chosen = IREFRAME_MODE;
DrawPart (m_hdc) ; ml_last_function_chosen = NO_FUNCTION_MODE;
}
void CBendCADViewPart: :OnViewShaded() { if (mi_show_solid) return; // Solid already being shown, int i;
BM_PART part = NULL; CBendCADDoc^ pDoc = GetDocument () ; ASSERT_VALID(pDoc) ; part = pDoc->get_part () ; if(! part) { mi_part_is_up_to_date = 0; return;
}
13 APPENDIX E mi_show_solid = 1; if (mi_show_3d) { if(! m_3d_base_clump) { i = facet_part_rw(part, „m_3d_base_clump, mi_show_3d, md_part_color) ; if( (! i) | | (! m_3d_base_clump) ) { mi_display_list_is_up_to_date = 0; return;
> >
RwRemoveClumpFromScene (m_base_clump) ; m_base_clump = m_3d_base_clump; // Set the base clump to be the 3d version's base clump.
RwAddClumpToScene (m_scene, m_base_clump) ; else { if(! m_flat_base_clump) { i = facet_part_rw(part, _m_flat_base_clump, mi_show_3d, md_part_color) ; if( (! i) | | (! m_flat_base_clump) ) { mi_display_list_is_up_to_date = 0; return;
> >
RwRemoveClumpFromScene (m_base_clump) ; m_base_clump = m_flat_base_clump; // Set the base clump to be the 3d version's base clump.
RwAddClumpToScene (m scene, m base clump);
} " " ml_last_function_chosen = SOLID_MODE;
DrawPart (m_hdc) ; ml_last_function_chosen - NO_FUNCTION_MODE;
void CBendCADViewPart: :OnZoomWindow()
{ ml_last_function_chosen = ZOOM_WINDOW_MODE; mi bbox is up to date = 0; } ~ " ~ " ~ void CBendCADViewPart : :OnUpdateZoomWindo (CCmdUI^ pCmdUI) pCmdUI->SetCheck( (Z00M_WIND0W_M0DE == ml last function chosen) ? TRUE : FALSE) ; - - _
}
14 APPENDIX E void CBendCADViewPart: :OnZoomInOut ()
{ ml_last_function_chosen = ZOOM_IN_OUT_MODE; mi bbox_is_up_to date = 0;
} " void CBendCADViewPart : :OnUpdateZoomInOut (CCmdUI^ pCmdUI)
{ pCmdUI->SetChec ( (ZOOM_IN_OUT_MODE == ml_last_function_chosen)
? TRUE : FALSE) ; } void CBendCADViewPart: :OnZoomAll () {
BM_PART part = NULL; CBendCADDoc^ pDoc; BM_VECTOR offset; if ( ! mi_bbox_is_up_to_date) ( pDoc = GetDocument () ; ASSERT_VALID(pDoc) ; part = pDoc->get_part () ; if ( ! part) return; if ( I mi_part_is_up_to_date) { // By now we expect the centroid to have already compute part_centroid (part , 0 ,
_m_f lat_part_centroid) ; (J been computed; this is only a safety check. compute_part_centroid(part, 1, _m_3d_part_centroid) ; if (mi_show_3d) m_part_centroid = m_3d_part_centroid; else m_j?art_centroid = m_f lat_part_centroid; compute_part_bbox (part , mi_show_3d, md_rot_matrix, m_part_centroid, md_part_bbox_size, -offset) ; mi_bbox_is_up_to_date = 1; md_x_trans = - (offset.X() ) ; // Adjust for the fact that bbox center may md_y_trans = - (offset.Y() ) ; // not coincide with centroid of part . } set_new_view_volume (md_part_bbox_size [0] ,md_part_bbox_size [1] ) ; ml_last_f nction_chosen = ZOOM_ALL_MODE;
DrawPart (m_hdc) ; ml last function chosen = NO FUNCTION MODE;
15 APPENDIX E void CBendCADViewPart : :OnUpdateZoomAll (CCmdUI^ pCmdUI)
{ pCmdUI->SetCheck( (ZOOM_ALL_MODE == ml_last_function_chosen) ?
TRUE : FALSE) ; }
void CBendCADViewPart: :OnViewIsometric ()
{ ml_last_function_chosen - ISOMETRIC VIEW MODE; mi_bbox_is_up_to_date = 0; md_z_angle = 270.0; md_y_angle = 305.2643897; // 270 + tan l(l/sqrt(2) )
RwRotateMatrix (RwScratchMatrix ( ) , 0. Of, 0.Of, 1. Of CREAL(md_z_angle) ,• rwREPLACE) ;
RwRotateMatrix (RwScratchMatrix{) , O.Of, l.Of O.Of, CREAL(md_y_angle) , rwPRECONCAT); md_z_angle = 45.0;
RwRotateMatrix (RwScratchMatrix ( ) , 0. Of O.Of l.Of CREAL (md_z_angle) , rwPRECONCAT) ; if (md_rot_matrix) RwDestroyMatrix (md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix (RwScratchMatrix ( ) )
// glPushMatrix() ;
// glLoadldentityO ;
// glRotated(md_z_angle, 0.0, 0.0, 1.0) ; // Rotation about z axis.
// glRotated(md_y_angle, 0.0, 1.0, 0.0) ; // Rotation about y axis .
// md_z_angle = 45.0;
// glRotated(md_z_angle, 0.0, 0.0, 1.0) ;
// glGetDoublev(GL_MODELVIEW_MATRIX, md_rot_matrix) ;
// glPopMatrix() ;
OnZoomAll () ;
void CBendCADViewPart: :OnViewRight () ml_last_function_chosen = RIGHT_VIEW_MODE; mi_bbox_is_up_to_date = 0; md_z_angle = 270.0; md_y_angle = 270.0; md_x_angle = 0.0;
RwRotateMatrix (RwScratchMatrix ( ) , O.Of O.Of, 1. Of, CREAL(md_z_angle) , rwREPLACE) ;
RwRotateMatrix (RwScratchMatrix () , O.Of 1. Of, O.Of, CREAL(md_y_angle) , rwPRECONCAT) ;
16 APPENDIX E if (md_rot_matrix) RwDestroyMatrix(md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix(RwScratchMatrix()) ;
// glPushMatrixO ;
// glLoadldentity() ;
// glRotated(md_z_angle, 0.0, 0.0, 1.0) ; // Rotation about z axis.
// glRotated(md_y_angle, 0.0, 1.0, 0.0) ; // Rotation about y axis.
// glGetDoublev(GL_MODELVIEW_MATRIX, md_rot_matrix) ;
// glPopMatrixO ;
OnZoomAll () ; }
void CBendCADViewPart: :OnViewFront ()
{ ml_last_function_chosen = FRONT_VIEW_MODE; mi_bbox_is_up_to_date = 0; md_y_angle = 0.0; md__z_angle = 0.0; md_x_angle = 270.0;
RwRotateMatrix (RwScratchMatrix () , l.Of, O.Of, O.Of, CREAL(md_x_angle) , rwREPLACE) ; if (md_rot_matrix) RwDestroyMatrix(md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix(RwScratchMatrix()) ;
// glPushMatrixO;
// glLoadldentity() ;
// glRotated(md_x_angle, 1.0, 0.0, 0.0) ; // Rotation about x axis.
// glGetDoublev(GL_MODELVIEW_MATRIX, md_rot_matrix) ;
// glPopMatrixO ,-
OnZoomAll 0 ; }
void CBendCADViewPart : :OnViewTop()
{ ml__last_function_chosen = TOP_VIEW_MODE; mi_bbox_is_up_to_date = 0; RwIdentityMatrix(md_rot_matrix) ;
OnZoomAll () ; } void CBendCADViewPart : :OnViewsOrtho()
{
17 APPENDIX E if (NULL == GetDocument () ->get_part () ) { // no part return ; }
COrthoViewDlg orhodlg(NULL, GetDocument () ->get_part , this) int ret = orhodlg.DoModal ;
// if we are in a Client Mode, the user cannot have entered anything.
// we have to redisplay the main client menu bar. if (BENDCAD_CLIENT_MODE) {
: :PostMessage(this->GetSafeHwnd() ,WM_COMMAND,MAKEWPARAM(ID_DISPLA Y_CLIENTJMENU, 1) ,NULL) ; return ;
}
// when OK pressed, get return values if (IDOK == ret) {
void CBendCADViewPart : :OnViewBack ()
{ ml_last_function_chosen = BACK_VIEW_MODE; mi_bbox_is_up_to_date = 0; md_x_angle = 270.0; md_y_angle = 0.0; md_z_angle - 180.0;
RwRotateMatrix (RwScratchMatrix() , l.Of, O.Of, O.Of CREAL(md_x_angle) , rwREPLACE) ;
RwRotateMatrix (RwScratchMatrix( ) , O.Of, O.Of, O.lf CREAL(md_z_angle) , rwPRECONCAT); if(md_rot_matrix) RwDestroyMatrix(md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix(RwScratchMatrix()) ;
OnZoomAll () ;
} void CBendCADViewPart: :OnViewBottom() ml_last_function_chosen = BOTTOM_VIEW_MODE; mi_bbox_is_up_to_date = 0; md_x_angle = 0.0; md_y_angle = 180.0; md_z_angle = 0.0;
18 APPENDIX E
RwRotateMatrix (RwScratchMatrix ( ) , O . O f , l . O f , O . Of ,
CREAL (md_y_angle) , rwREPLACE) ; if (md_rot_matrix) RwDestroyMatrix (md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix (RwScratchMatrix ( ) ) ;
OnZoomAll O ; } void CBendCADViewPart : :OnViewLeft 0
{ ml_last_function_chosen = LEFT_VIEW_MODE; mi_bbox_is_up_to_date = 0,- md_z__angle = 90.0; md_y_angle = 90.0; md_x_angle = 0.0;
RwRotateMatrix(RwScratchMatrix () , O.Of, O.Of, l.Of, CREAL(md_z_angle) , rwREPLACE) ;
RwRotateMatrix (RwScratchMatrix () , O.Of, l.Of, O.Of, CREAL( d_y_angle) , rwPRECONCAT); if (md_rot_matrix) RwDestroyMatrix(md_rot_matrix) ; md_rot_matrix = RwDuplicateMatrix(RwScratchMatrix0 ) ;
OnZoomAll 0 ; }
void CBendCADViewPart : :OnRotate ()
{ ml_last_function_chosen = ROTATION_MODE; mi bbox is up to date = 0; } " " void CBendCADViewPart : :OnUpdateRotate (CC dUI^ pCmdUI)
{ pCmdUI->SetCheck( (ROTATION_MODE == ml_last_function_chosen) ? TRUE : FALSE) ;
}
void CBendCADViewPart: :OnPa () { ml_last_function_chosen - PAN_MODE; mi_bbox_is_up_to_date = 0;
} void CBendCADViewPart: :OnUpdatePan(CCmdUI^ pCmdUI) pCmdUI->SetCheck ( (PAN_MODE == ml_last_function_chosen) ? TRUE
19 APPENDIX E
: FALSE) ; }
// This function computes the rotation angles about x and y axes. // It is called on mouse movement, if the rotation mode is on. void CBendCADViewPart: :compute_rotation_angles(int x_flag)
{
Figure imgf000401_0001
// else
// glRotated(md_z_angle, 0.0, 0.0, 1.0); // Rotation about z axis.
// glMultMatrixd(md_rot_matrix) ;
// glGetDoublev(GL_MODELVIEW_MATRIX, md_rot_matrix) ;
// glPopMatri ;
}
// This function computes the x and y translation values. // It is called on mouse movement, if the pan mode is on. void CBendCADViewPart: :compute_pan_translation(void) double x; if( (x = (double)m_old_rect.right) > 0.0 ) md_x_trans += (m_current_point.x - m_previous_point.x) ♦ md_current_view_vol [0] /x; if ( (x = (double)m_old_rect.bottom) > 0.0 ) md_y_trans += - (m_current_point.y - m_previous_point.y) ♦ //
20 APPENDIX E
-ve sign for md_y_trans md_current_view_vol[1] /x; // bee. y axis points up screen.
}
// This funciton computes translation values when user zooms in/out. void CBendCADViewPart: :compute_zoom_in_out_translation(void)
{ double x; if ( (x = (double)m_old_rect.right) > 0.0 ) md_x_trans += - (m_current_point.x - m_previous_point.x) md_current_view_vol[0] /x;
}
// This funciton computes translation values when user zooms into a
// selected rectangular region. void CBendCADViewPart: :compute_zoom_region_translation(void)
{ double xl - ((double) (m_lt_btn_down_point . + m_lt_btn_up_point.x) ) /2.0; double delta_x = xl - ( (double)m__old_rect.right) /2.0; double yl = ((double) (m_lt_btn_down_point .y + m_lt_btn_up_point.y) )/2.0; double delta_y = - ( yl - ( (double)m_old_rect.bottom) /2.0 ); md_x_trans -= //m_part_centroid.X0 - md_x_trans + delta_x+2.0+md_current_view_vol[0] / ( (double)m_old_rect.right) ; md_y_trans -= //m_part_centroid.Y() - md_y_trans + delta yA2.0^md current view vol [1] /( (double)m old rect.bottom) ; }
// This function computes the new view volume when the user zooms in/out.
// The part has already been translated appropriately. v{oid CBendCADViewPart::compute-zoom-in-out--view-volume(void) double x = - (m__current_point.y - m_previous_point.y) ; m d _ c u r r e n t _ v i e w _ v o l [ 0 ] - = md_current_view_vol [0] x/ (double) m_old_rect . bottom; md_current_view_vol[1] = md_current_ iew_vol [0] /md_aspect; RwSetCameraViewwindow(m_camera, (float) (md_current_view_vol [0] ) , (float) (md_current_view_vol[1] ) ) ;
21 APPENDIX E glMatrixMode (GL_PROJECTION) ; glLoadldentity() ; glOrtho(- md_current_view_vol [0] , md_current_view_vol [0] , md_current_vi ew_vol [ l ] , md_current_view_vol [1] , // - 50000.0, 50000.0) ;
- md_current_view_vol [2] , md_current_view_vol [2] ) ; glMatrixMode (GL_MODELVIEW) ;
}
// This function computes and sets the new view volume when the user zooms into
// a selected rectangular region. (In the case of zoom all, the selected
// region is simply the bounding box of the part) .
// The part has already been translated appropriately. void CBendCADViewPart: :set_new_view_volume (double x_extent, double y extent)
{" double longer = max(x_extent, y_extent) ; double shorter = min(x_extent, y_extent) ; if (longer == x_extent) { // The x extent is longer. if (longer/md_aspect < shorter) // y extent does not fit screen. longer = shorter^md_aspect;
lo fi
Figure imgf000403_0001
longer = shorter/md_aspect; md_current_view_vol [0] = 0.55Λlonger^md_aspect; md_current_view__vol [1] = 0.55longer; md_current_view_vol [2] = maxdonger, md_part_bbox_size [2] ) ;
RwSetCameraViewwindow(m_camera, (float) (md_current_view_vol [0] ) , (float) (md_current_view_vol [1] ) ) ; glMatrixMode (GL_PROJECTION) ; glLoadldentity() ; glOrtho(- md_current_view_vol [0] , md_current_view_vol [0] , md_current_view_vol [ 1 ] , md_current_view_vol [1] ,
22 APPENDIX E
// - 50000.0, 50000.0) ;
- md_current_view_vol [2] , md_current_view_vol [2] ) ; glMatrixMode (GL_MODELVIEW) ; glLoadldentityO ;
// This function draws a part on the view window. It is called by
OnDraw. void CBendCADViewPart : :DrawPart (HDC draw_dc)
{ long size, i, parent_tag, key; static long ♦selected_items = NULL;
RwClump ♦pic ed^lump, parent_clump; static double red_color[3] = {1.0, 0.0, 0.θ}; static double green_color[3] = (0.0, 1.0, 0.0} ; double array[16] ;
BV_SELECT_DATA +data = NULL; static RwMatrix4d old_matrix[50] ; static float rw_array[4] [4] ; if (mi_simulation_is_on) { // Set camera parameters to view window values.
RwSetCameraViewport (m_camera, 0, 0, m_old_rect.right, m_old_rect.bottom) ; glViewport (0, 0, m_old_rect.right, m_old_rect.bottom) ;
Rw S e t C a m e r aV i e ww i n do w ( m_ c a m e r a , (float) (md_current_view_vol [0] ) , (float) (md_current_view_vol [1] ) ) ; glMatrixMode (GL_PR0JECTI0N) ; glLoadldentity 0 ; glOrtho(- md_current_ iew_vol [0] , md_current_view_vol [0] , md_cu r r e n t _v i ew_vo 1 [1] , md_current_view_vol [1] , // - 50000.0, 50000.0) ;
- md_current_view_vol [2] , md_current_view_vol [2] ) ; glMatrixMode (GL MODELVIEW) ;
} if ( ! mi_show_solid) { // Wireframe drawing; use OpenGL drawing commands. glPushMatrix() ; glTranslated (m_camera_pos it ion . X ( ) , m_camera_position. Y () , m_camera_position. Z () ) ; gluLookAt (m_camera_pos it ion. X () , m_camera_position. Y 0 , m_camera_position. Z () , m_camera_target . X ( ) ,
23 APPENDIX E m_camera_target .Y0 , m_camera_target.Z () , m_camera_look_up.X() , m_camera_look_up.Y0 , m_camera_look_up.Z () ) ; glTranslated(md_x_trans, md_y_trans, 0.0) ; convert_rw_matrix_to_gl_array(md_rot_matrix, array) ; glMultMatrixd(array) ; glTranslated(- m_part_centroid.X 0 , - m_part_centroid.Y() , - m_part_centroid.Z () ) ; glClearColor(0.0f, O.Of, O.Of, l.Of) ; glClear(GL_COLOR_BUFFER_BIT j GL_DEPTH_BUFFER_BIT) ; if (ml_last_function_chosen == SELECT_OBJECTS_MODE) glRenderMode(GL_SELECT) ; else glRenderMode(GL_RENDER) ;
glSelectBuffer(512, mw_selected_objects) ; gllnitNames 0 ; glPushName (0) ; if ( ! mi_simulation_is_on) {
// First draw the selected items in red, if any. size = selection set. list size () ; if (size) { selected_items = new long [size^2 + 1] ; // +1 for safety. m_selection_set.display(size, selected_items) ; glColor3d(1.0, 0.0, 0.0) ; for(i=0; i < size; ++i) { data = (BV SELECT DATA )selected items [iΛ2
+1] ; if ( ! data) continue; if (data->edge) { // Edge is available, => not a trivial g l C a l l L i s t ( ( u n s i g n e d int) selected_items [i<<l] ) ; // bendline or body of something . else {
// Body of face/forming/bendline picked; highlight whole thing. key = selected_items [i<<l] /100000 ; glCallList ( (unsignedint) key^lOOOOO) ;
I ' '
24 APPENDIX E glCallList (1) ; glFinishO ; glPopMatrixO ; SwapBuffers(wglGetCurrentDC0 ) ;
} else ( // Solid drawing; use RenderWare.
// Transform the part if necessary, if (ml_last_function_chosen != NO_FUNCTION_MODE) { RwTranslateMatrix (RwScratchMatrix () , CREAL (md_x_trans) , CREAL (md_y_trans ) , CREAL (0.0) , rwREPLACE) ;
RwTransf ormMatrix (RwScratchMatrix ( ) , md_rot_matrix, rwPRECONCAT) ;
RwTrans lateMatrix ( RwScratchMatrix ( ) , CREAL ( - m_part_centroid . X () ) , CREAL ( - m_part_centroid . Y 0 ) ,
CREAL (- m_ art_centroid.Z() ) , rwPRECONCAT) ;
// RwForAllClumpsInScenePointer (m_scene, do_transf ormations, (void ♦ ) RwScratchMatrix () ) ;
RwTransf ormClump(m_base_clump, RwScratchMatrix ( ) , rwREPLACE) ;
}
/*
RwClump clump; for(i=0; i < ml_num_faces + ml_num_bendlines + ml_num_formings;
++i) { clump = RwFindTaggedClump (m_base_clump, i + 10001) ; if ( ! clump) continue; old_matrix[i] = RwCreateMatrix 0 ; / /
Store the current modeling matrix of the clump. RwGetClumpMatrix (clump, old_matrix [i] ) ;
RwGetMatrixElements (old_matrix [ij , rw_array) ; RwTranslateMatrix (RwScratchMatrix () , CREAL (md_x_t ran s) , CREA (md_y_trans) , CREAL (0.0) , rwREPLACE);
RwTransf ormMatrix (RwScratchMatrix ( ) , md_rot_matrix, rwPRECONCAT) ;
RwTrans la t eMat rix ( RwScr at chMat rix ( ) , CREAL ( - m_part_centroid . X () ) , CREAL ( - m_part_centroid . Y () ) ,
CREAL (- m_part_centroid.Z() ) , rwPRECONCAT) ; //RwForAllClumpsInScenePointer (m_scene , do_transf ormations, (void ) RwScratchMatrix ()) ;
RwTransformClump(clump, RwScratchMatrix() , rwPOSTCONCAT) ;
} */
// Now set the color of the clumps in the selection set to red.
25 APPENDIX E size - m_selection_set. list_size () ; if (size) { selected_items = new long [(size << 1) + 1] ; // +1 for safety. m_selection_set .display(size, selected_items) ; for(i=0; i < size; ++i) { data = (BV_SELECT_DATA ) selected_items [i^2
+1] ; if ( ! data) continue; if (data->edge) { // Edge is available,
=> not a trivial bendline or body of something. parent_tag = (selected_items [i<<l] /100000) + 10000; p a r e n t _ c l u m p RwFindTaggedClump(m_base_clump, parent_tag) ; else ( key = selected_items [i<<l] %100000; // Check if it is a trivial bendline. if ( (key/10000) _= 6) { p a r e n t _ t a g (selected_items [i<<l] /100000) + 10000; p a r e n t _ c l u m p =
RwFindTaggedClump (m_base_clurnp, parent_tag) ; else parent_clump = m_base_clump; key = selected_items [i<<l] %100000; picked_cl_mp = RwFindTaggedClump (parent_clump, key) ,-
RwForAllPolygonsInClumpPointer(picked_clump, SetPolygonColor, (void #)red color);
) '
// In case simulation is going on, we don't want to show the m_sim_base_clump, only m_base_clump. if (mi_simulation_is_on) { i f ( m _ s i m _ b a s e _ c l u m p ) RwRemoveClumpFromScene (m_sim_base_clump) ; if (mi_show_3d) { m_base_clump = m_3d_base_clump; RwAddClumpToScene (m_scene, m_base_clump) ; else { m_base_clump = m_flat_base_clump; RwAddClumpToScene (m_scene, m_base_clumρ) ,-
26 APPENDIX E
// Now draw the part. RwInvalidateCameraViewport (m_camera) ;
RwBeginCameraUpdate(m_camera, (void )m_hwnd) ; RwClearCameraViewport (m_camera) ; i = RwGetSceneNumClu ps (m_scene) ; // Render the scene.
RwRenderScene (m_scene) ; RwEndCameraUpdate (m_camera) ;
RwShowCameralmage (m_camera, (void^) (DWORD)draw_dc) ; // Show the image on the view window.
/* for(i=0; i < ml_num_faces + ml_num_bendlines + ml_num_formings; ++i) { clump = RwFindTaggedClump(m_base_clump, i + 10001) ; if ( ! clump) continue;
RwTransformClump (clump, old_matrix[i] , rwREPLACE) ; RwGetClumpMatrix(clump, old_matrix[i] ) ;
RwGetMatrixElements (old_matrix [i] , rw_array) ; if (old matrix[i] ) RwDestroyMatrix(old_matrix[i] ) ;
} /
// Put the simulation clump back in the scene so that simulation can see it. if (mi_simulation_is_on) { if (m_sim_base_clump) RwAddClumpToScene(m_scene, m_sim_base_clump) ; i f ( m i _ s h o w _ 3 d ) RwRemoveClumpFromScene (m_3d_base_clump) ; else RwRemoveClumpFromScene(m_flat_base_clump) ; m base clump = NULL; }
// Now set the color of the clumps in the selection set back to their original colors, if (size) { m_selection_set.display(size, selected_items) ; for(i=0; i < size; ++i) { data = (BV_SELECT_DATA ) selected_items [i*2
+1] ; if (data->edge) ( // Edge is available, => not a trivial bendline or body of something. parent__tag = (selected_items [i<<l] /100000) + 10000; p a r e n t _ c l u m p RwFindTaggedClump (m_base_c__mp , parent_tag) ; else (
27 APPENDIX E key = selected_items [i<<l] %100000; // Check if it is a trivial bendline. if ( (key/10000) == 6) { p a r e n t _ t a g (selected_items [i<<l] /100000) + 10000; p a r e n t _ c l u m p RwFindTaggedClump (m_base_c lump, parent_tag) ; else parent_clump = m_base_clump;
} key = selected_items [i<<l] %100000; picked_clump = RwFindTaggedClump (parent_clump, key) ; if( (! data->edge) __ ((key/10000) == 6) ) // Trivial bendline.
RwForAllPolygonsInClumpPomter(picked_clump, SetPolygonColor, (void ♦)green_color) ; else
RwForAllPolygonsInClumpPointer(picked_clump, SetPolygonColor, (void ♦)md_part color);
if (selected_items) delete [] selected_items; selected items = NULL;
} if (mi_simulation_is_on) { // Restore camera parameters to simulation values.
RwSetCameraViewport (m_camera, 0, 0, mi_bitmap_w , mi_bitmap_h) ; glViewport (0, 0, mi_bitmap_w, mi_bitmap_h) ;
R w S e t C a m e r a V i e w w i n d o w ( m _ c a m e r a , (float) (md_sim_view_vol [0] ) , (float) (md_sim_view_vol [1] ) ) ; glMatrixMode (GL_PROJECTION) ; glLoadldentity 0 ; glOrtho (- md_sim_view_vol [0] , md_sim_view_vol [0] , md_ s i m_vi ew_vo l [ l ] , md_sim_view_vol [1] ,
// - 50000.0, 50000.0) ;
- md_current_view_vol [2] , md_current_view vol [2] ) ; glMatrixMode (GL_MODELVIEW) ;
}
28 APPENDIX E
/* if (size) { for(i=0 ,- i < size; ++i) ( BM_3D_BODY ^b3 ; long three_d_type; if (selected_items [i^2 +1]) { // Edge is available, => not a trival bendline or forming. three_d_type = (selected_items [i<<l] %100000) /10000; if ( (three_d_type >= 3) __ (three_d_type < 6)) three_d_type = BM_ENTITY_TYPE_FACE; else if ( (three_d_type >= 6) __ (three_d__type < 9)) three_d_type = BM_ENTITY_TYPE_BENDLINE; else if (three_d_type >= 9) three_d_type = BM_ENTITY_TYPE_FORMING; parent_tag = (selected_items [i<<l] /100000) + 10000; parent_clump = RwFindTaggedClump (m_base_clump, parent tag) ;
" e}lse {
CBendCADDoc^ pDoc = GetDocument 0 ;
ASSERT_VALID(pDθC) ;
BM_PART ♦part = pDoc->get_part () ; if ( ! part) return; // Note: we do not expect part to be NULL at this stage.
BM_TOPOLOGY topology = part->get_topology0 ; if ( ! topology) return; three_d_type = selected_items [i<<l] /100000; //
Terminology caution: three_d_type is not really b3 = topology->map_id_into_pointer(three_d_type) ,- // a three_d_type until b3->get_type 0. three_d_type = b3->get_type () ; parent_clump - m_base_clump; if (three_d_type == BM_ENTITY_TYPE_FACE) { for(j=0; j < 3; ++j) original_color[j] md face color [j] ;
" " e}lse if (three_d_type == BM_ENTITY_TYPE_BENDLINE) { for(j=0; j < 3; ++j) original_color [j] md_bendline_color [ j ] ; else if (three_d_type == BM_ENTITY_TYPE_FORMING) ( for(j=0; j < 3; ++j) original_color [j] md_f orming color [j]; key = selected_items [i<<l] ,- key = key%100000; picked_clump = RwFindTaggedClump (parent_clump, key) ; RwForAllPolygonsInClumpPointer (picked_clump , SetPolygonColor, (void ♦) original_color) ;
29 APPENDIX E }
} * /
// This callback function performs the necessary transformations on each clump in the scene.
// Transform only parent clumps, since this automatically transforms child clumps as well. static RwClump ♦ RWCALLBACK do_transformations (RwClump clump, void
♦matrix)
{ int i = RwGetClumpNumChildren(clump) ; if(i) { if ( ! (i = RwGetClumpNumPolygons (clump) ) ) RwSetClu pState(clump, rwOFF) ; // Do not render this clump if it has no polygons.
RwTransformClump(clump, (RwMatrix4d )matrix, rwREPLACE) ;
} return clump;
}
// This callback function sets the color of the polygon to the required color. static RwPolygon3d RWCALLBACK SetPolygonColor(RwPolygon3d ♦polygon, void color)
{ polygon = RwSetPolygonColor(polygon, CREAL (( (double
♦) color) [0] ) , CREAL (( (double ) color) [1] ) ,
CREAL ( ( (double
♦)color) [2])) ; return polygon;
}
// This function sets the pixel format of the view window to the kind that
// OpenGL likes. Note: Pixel format of a window should be set only once.
BOOL CBendCADViewPart : :SetupPixelFormat (HDC hDC) static PIXELFORMATDESCRIPTOR pfd = { sizeof (PIXELFORMATDESCRIPTOR) , // size of this pfd
! // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
30 APPENDIX E
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
} int pixelformat ; if ( (pixelformat = ChoosePixelFormat (hDC, _pf d) ) == 0 )
MessageBox O' ChoosePixelFormat failed" ) ; return FALSE ;
} if (SetPixelFormat (hDC, pixelformat, _pfd) == FALSE)
{
MessageBox("SetPixelFormat failed") ; return FALSE; }
// don't need this call any more; the function will be called from OnActivateViewO
// and on OnViewWireframe () -- AK //CreateRGBPalette(hDC) ; return TRUE; }
unsigned char CBendCADViewPart: :ComponentFromlndex(int i, UINT nbits, UINT shift)
{ unsigned char val; val = (unsigned char) (i >> shift) ; switch (nbits) { case 1 : val 8 = 0x1; return onetoβ [val] ; case 2 :
31 APPENDIX E val Sc= 0x3; return twotoδ [val] ; case 3 : val S= 0x7; return threetoθ [val] ; default : return 0;
}
void CBendCADViewPart : :CreateRGBPalette (HDC hDC)
{ PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE ♦pPal; int n, i;
CDC dc; n = : :GetPixelFormat (hDC) ;
: :DescribePixelFormat (hDC, n, sizeof (PIXELFORMATDESCRIPTOR) , -pfd) ; if (pfd.dwFlags _ PFD NEED PALETTE)
{ " ~ n - 1 << pfd.cColorBits; pPal = (PLOGPALETTE) LocalAlloc (LMEM_FIXED, sizeof (LOGPALETTE) + n sizeof (PALETTEENTRY) ) ; pPal->palVersion = 0x300; pPal->palNumEntries = n; for (i=0; i<n; i++)
{ pPal->palPalEntry [i] .peRed =
ComponentFromlndex (i, pfd.cRedBits, pfd.cRedShift) ; pPal->palPalEntry[i] .peGreen =
ComponentFromlndex (i , pfd. cGreenBits, pfd. cGreenShif t) ; pPal->palPalEntry [i] .peBlue =
ComponentFromlnde (i , pfd. cBlueBits, pfd.cBlueShift) ; pPal->palPalEntry [i] .peFlags = 0 ;
/ fix up the palette to include the default GDI palette ♦/ if ((pfd.cColorBits == 8) &&
(pfd.cRedBits == 3) _& (pfd.cRedShift == 0) ScSc (pfd. cGreenBits == 3) SS (pf d. cGreenShif t == 3) __ (pfd. cBlueBits == 2) ScS< (pfd.cBlueShift == 6)
32 APPENDIX E
)
{ for ( i = 1 ; i <= 12 ; i++) pPal - >pa l Pa l Ent ry [ de f au l tOve rride [ i ] ] def aultPalEntry [i] ,-
} dc . Attach (hDC) ;
CPalette pOldPal;
// since we call this function not only when creating a view,
// but also each time activating, delete the prev palette (if any) -- AK int resp = m_cPal.DeleteObject () ; m_cPal .CreatePalette (pPal) ;
LocalFree (pPal) ; pOldPal = dc.SelectPalette(_m_cPal, FALSE) ; dc.RealizePalette () ; dc .Detach0 ;
// This function computes the bounding box parameters of the given part -
// the x, y and z extents, in global coordinates, for the orientation specified by orient_matrix.
// The computation is done with respect to the BM_POINT centroid as origin.
// It does so by taking the bbox of each face, projecting each onto the coordinate
// axes, and then finding the extents along each axis. If threeD_flag is non-zero, the
// three-d version's bbox is computed; else, the flat's bbox is computed. The results of the
// computation are put into the arry bbox_size[3] ; if this pointer is zero, no computation
// is performed. The offset, ie. the vector from the centroid' s coords to the bbox center's coords,
// is passed back in the pointer to the BM_VECTOR.
// Returns 1 if successful, 0 otherwise. int CBendCADViewPart: :compute_part_bbox(BM_PART part, int threeD_flag, RwMatrix4d ♦orient_matrix,
BM_POINT centroid, double bbox size, BM VECTOR offset)
{
33 APPENDIX E
BM_FACE face = NULL; BM_BENDLINE ♦bendline = NULL; BM_2D_BODY two_d_body = NULL; BM_LOOP loop = NULL; BM_POINT dotl, dot2, dot3, dot4 ; double left, right, top, bot, front, back; // First two refer to x direction, // last two to z direction. BM_VECTOR vecl; int first_pass = 1; float rot matrix [4] [4] ; if ( ! part) return 0; if ( ( par t - >ge t_number_of _f ace s ( ) 0) ScSc part->get_number_of_bendlines () == 0) ) rreettuurrnn 00; ; if ( ! bbox size) return 0; if ( I part->get_number_of_faces ()) { // In this case, find bendline bboxes. for(bendline = part->get_bendline_list () ; bendline; bendline = (BM_BENDLINE )bendline->next () ) {
// First check that the bbox of the bloop is up to date; if not compute bbox. if (threeD_flag) two_d_body = bendline->get_3D_version () ; else two_d_body = bendline->get_flat () ; if (two_d_body) loop = two_d_body->get_bloop () ; else continue; if ( ! loop) continue; if ( ! (loop->is_bbox_up_to_date () ) ) loop->recompute_bbox () ;
// Now find the envelope (union) of the projected bboxes. vecl = BM_VECTOR(centroid.X , centroid.Y() , centroid.Z ()) ; dotl = loop->get_bbox_pl () + (-1.0) ♦vecl // The bbox coordinates, dot2 = loop->get_bbox_p2 () + (-1.0) ♦vecl // with respect to the dot3 = loop->get_bbox_p3 () + (-l.0)*vecl // centroid as origin. dot4 = loop->get_bbox_p4 () + (-1.0) ♦vecl
RwGetMatrixElements (orient_matrix, rot_matrix) ; multiply_jpt_by_matrix(_dotl, rot_matrix) ; // Transform coords by the current multiply_pt_by_matrix(_dot2, rot_matrix) ; // rotation matrix.
34 APPENDIX E multiply_pt_by_matrix ( _dot3 , rot_ matrix) mult iply_pt_by_matrix ( Scdot 4 , rot_ matrix) if (first _pass) { left = min(dotl.X() dot2 .XO) ; right = max(dotl.X() dot2 .XO) ; bot = min(dotl.Y() dot2 •Y0 ) ; top = max(dotl.Y() dot2 ■YD) ; back = min(dotl.ZO dot2 •ZO); front = max(dotl.ZO dot2 •ZO) ; first_pass = 0;
} else { left mm (left, dotl.X left min(left, dot2.X right max(right, dotl.X right max(right, dot2.X bot min(bot dotl.Y bot min(bot , dot2.Y top max(top , dotl.Y top max(top dot2.Y back _min(back , dotl.Z back min(back , dot2.Z front max (front, dotl.Z front max(front, dot2.Z
} left _ min (left, dot3.X( left = min(left, dot4.X( right = max(right, dot3.X( right = max(right, dot4.X( bot min(bot , dot3.Y( bot _min(bot dot4.Y( top max(top , dot3. Y( top max(top , dot4.Y( back min(back , dot3.Z( back min(back , dot4.Z( front = max(front, dot3.Z( front = max(front, dot4.Z (
} bbox_size [0] right left; bbox_size [lϊ top bot; // Copy bbox size into the array passed. bbox size [2] = front - back; if (offset) // Copy the bbox center into the pointer passed.
offset = BM_VECT0R( (right + left)/2.0, (top + bot)/2.0, (front + back)/2.0) ; mi_bbox_is_up_to_date = 1;
35 APPENDIX E return 1;
}
// Faces are available, so find bbox of faces. for (face = part->get_face_list () ; face; face = (BM_FACE ♦) face->next 0 ) { if ( ! face) break;
// First check that the bbox of the bloop is up to date; if not compute bbox. if (threeD_flag) two_d_body = face->get_3D_version () ; else two_d__body = face->get_flat () ; if (two_d_body) loop = two_d_body->get_bloop() ; else continue; if ( ! loop) continue; if ( ! (loop->is_bbox_up_to_date 0 ) ) loop->recompute_bbox() ;
// Now find the envelope (union) of the projected bboxes. vecl = BM_VECTOR(centroid.X () , centroid.Y() , centroid.Z ()) ; dotl = loop->get_bbox_pl () + (-1.0) vecl // The bbox coordinates, dot2 = loop->get_bbox_p2 () + (-1.0) vecl // with respect to the dot3 = loop->get_bbox_p3 () + (-1.0) vecl // centroid as origin. dot4 = loop->get_bbox_jp4 () + (-1.0)+vecl
RwGetMatrixElements (orient matrix, rot matrix) multiply_pt_by_matrix(_dotl, rot_matrix) // Transform coords by the current multiply_jpt_by_matrix (_dot2 , rot_matrix) // rotation matrix. multiply_pt_by_matrix (_dot3 , rot_matrix) multiply_pt_by_matrix ( _dot4 , rot_matrix) if (f irst_pass) { left = min (dotl.X () , dot2.X() right = max (dotl.X (), dot2.X() bot = min (dotl. YO , dot2.Y() top = max (dotl. Y () , dot2.Y() back = min(dotl.Z(), dot2.Z() front = max (dotl. Z , dot2.Z() first pass = 0;
} else { left = mindeft, dotl.XO); left = mindeft, dot2.X());
36 APPENDIX E right = max(right, dotl.XO ) right = max(right, dot2.X() ) bot = min(bot , dotl.YO ) bot = min(bot , dot2.Y() ) top = max(top , dotl.YO ) top = max(top , dot2.Y() ) back = min(back , dotl.Z () ) back = min(back , dot2.Z() ) front = max(front, dotl.Z (] ) front = max(front, dot2.Z () )
} left - _min(left, dot3.X() ) left = _min(left, dot4.X() ) right = _max(right, dot3.X() ) right = jnax(right, dot4.X() ) bot _miή(bot , dot3.Y() ) bot _min(bot , dot4.Y() ) top _max(top , dot3.Y() ) top _max(top , dot4.Y() ) back _min(back , dot3.Z() ) back _min(back , dot4.Z() ) front = _max(front, dot3.Z() ) front = _max(front, dot4.Z() ) } bbox_size [0] = right - left; bbox_size [1] = top bot; / <7/ Copy bbox size into the array passed. bbox size [2] = front - back; if (offset) // Copy the bbox center into the pointer passed.
♦offset = BM_VECTOR( (right left)/2.0, (top + bot)/2.0, (front + back) /2.0) ; mi_bbox_is_up_to_date - 1; return 1;
// This function computes the part's centroid. This is done with respect to
// the original (given) coordinates of the part. If threeD_flag is non-zero, the
// three-d version's centroid is computed; else, the flat's centroid is computed.
// The results are passed back in the pointer to a BM_POINT; if this pointer is NULL, no
// computation is done. Returns 1 if successful, 0 otherwise.
37 APPENDIX E int CBendCADViewPart : :compute_part_centroid(BM_PART part, int threeD flag, BM_POINT ♦centroid)
{
BM_FACE face; BM_2 D_BODY two_d_body ; BM_LOOP loop;
BM_POINT dotl, dot2, dot3, dot4 ; double left, right, top, bot, front, back; // First two refer to x direction,
// last two to z direction. int first_pass = 1; if ( ! part) return 0; if ( ( p a r t - > g e t _numbe r _o f _ f a c e s == 0 ) Sc _
(part->get_number_of_bendlines == 0) ) return 0 ,- if ( ! centroid) return 0 ; for (face = part->get_face_list () ; face; face = (BM_FACE ♦) face->next () ) { if ( ! face) break;
// First check that the bbox of the bloop is up to date; if not compute bbox. if (threeD_flag) two_d_body = face->get_3D_version() ; else two_d_body = face->get_flat () ; if (two_d__body) loop - two_d_body->get_bloop () ; else continue; if ( ! loop) continue; if ( ! (loop->is_bbox_up_to_date () ) ) loop->recompute_bbox0 ;
// Now find the envelope (union) of the projected bboxes. dotl = loop->get_bbox_pl () dot2 = loop->get_bbox_p20 dot3 = loop->get__bbox_p3 O dot4 = loop->get_bbox_jp4 () if (first pass) ( left = min(dotl.X() , dot2.X() right = max(dotl.XO , dot2.X() bot = min(dotl.Y() , dot2.Y() top = max(dotl.Y() , dot2.Y() back = min(dotl.Z() , dot2.Z() front = max(dotl.Z () , dot2.Z() first_pass = 0;
38 APPENDIX E else { left _ min deft, dotl.XO ) left = min deft, dot2.X() ) right = max(right ., dotl.XO) right = max(right , dot2.XO) bot = min(bot , dotl.YO) bot = min(bot , dot2.Y0) top = max(top , dotl.YO) top - max(top , dot2.YO) back _ min(back , dotl.Z ()) back = min(back , dot2.ZO ) front _ max(front, dotl.Z ()) front = ma (front, dot2.Z())
} left - _mindeft, dot3.X() ) ; left = _mindeft, dot4.X() ) ; right = _max(right, dot3.X() ) ; right = _max(right, dot4.X0 ) ; bot _min(bot , dot3.Y() ) ; bot _min(bot , dot4.Y() ) ; top = _max(top , dot3.Y() ) ; top _max(top , dot4.Y() ) ; back _min(back , dot3.Z() ) ; back = _min(back , dot4.Z() ) ; front = _max(front, dot3.Z() ) ; front = max(front, dot4. Z() ) ;
}
♦centroid = BM_P0INT ( (right + left)/2.0, (top + bot )/2.0, (front + back)/2.0) ; // Copy centroid into
/*
// pointer supplied if (threeD_flag) { m_3d_part_centroid.set_X( (right + left)/2.0); m_3d_part_centroid.set_Y( (top + bot )/2.0); // The part' s 3d centroid.
} _3d_part_centroid.set Z((front + back)/2.0) ; else { m_flat_part_centroid.set_X( (right + left)/2.0) m_flat_part_centroid.set_Y( (top + bot )/2.0) // The part's flat centroid. m flat part centroid.set Z( (front + back)/2.0)
} ~ " ~ */ return 1;
}
39 APPENDIX E
// This function multiplies a bend model point by a 4x4 RenderWare transform matrix.
// The function is destructive. It is NOT a BMAPPView member function.
// Note that the point is considered to be a row vector; this is
// RenderWare's (and the Bend Model's) convention. static void multiply_pt_by_matrix(BM_P0INT point, float rot matrix[4] [4] )
{ " double x = point ->X() double y = point ->Y() double z = point ->Z() point->set_X( (x^rot_matrix [0] [0] + y^rot_matrix [1] [0] + z^rot_matrix[2] [0] ) ) ; point ->set_Y( (xΛrot_matrix [0] [1] + y^rot_matrix [1] [1] + z + rot_matrix[2] [1] ) ) ; point->set_Z ( (x^rot_matrix [0] [2] + y+rot_matrix [1] [2] + z^rot_matrix[2] [2] ) ) ;
}
// This function outlines the rectangular region selected by the user. void CBendCADViewPart ::outline region(void)
{
CClientDC view_dc (this) ;
CPoint cornerl_curr = m_lt_btn_down_point , corner2_curr m_lt_btn_down_point ;
CPoint cornerl_prev = m_lt_btn_down_point , corner2_prev m_lt_btn_down_point ; cornerl_curr .Offset (m_current_point.x - m It btn down point. x, 0) ; _ _ _ co r ne r 2_cur r . O f f s e t ( 0 , m_ c u r r e n t _p o i n t . y m_lt_btn_down_point .y) ; cornerl_prev. Offset (m_previous_point.x - m_lt_btn_down_point .x, u / ; c or ne r 2_pr e v . Of f s e t ( 0 , m_p r e v i ou s_p o i n t . y m_lt_btn_down_point .y) ; view_dc.SetROP2 (R2_NOT) ; view_dc.MoveTo(m_lt_btn_down_point) ; view_dc.LineTo(cornerl_prev) ; view_dc. oveTo(m_lt_btn_down_point) ; view_dc.LineTo(corner2_prev) ;
40 APPENDIX E view_dc.MoveTo(cornerl_prev) ; view_dc.LineTo (m_previous_point) ; view_dc.MoveTo(corner2_prev) ; view_dc.LineTo (m_previous_point) ; view_dc.MoveTo(m_lt_btn_down_point) ; view_dc.LineTo(cornerl_curr) ; view_dc.MoveTo(m_lt_btn_down_point) ; view_dc.LineTo(corner2_curr) ; view_dc. oveTo(cornerl_curr) ; view_dc.LineTo(m_current_point) ; view_dc.MoveTo(corner2_curr) ; view_dc.LineTo (m_current_point) ;
// This function processes the hits record to pick out the edge(s) selected by the
// user. If add_hit_to_list is non-zero, which it is if the control button is held down,
// the current hit, if any, is added to the selection set; else, the selection set
// is cleared and only the current hit is added to the list. If there is no hit, the
// selection set is cleared as well, unless add_to_list is non-zero, in which case
// nothing happens.
// This function recognizes trivial bendlines and formings and modifies the selection set
// appropriately. v {oid CBendCADViewPart: :process hits recorddnt add-hit-to-list)
RwClump picked_clump - NULL; RwClump parent_clump = NULL;
RwV3d vert; long parent_tag, clump_tag, three_d_type = 0, offset = 0, key = 0; int num_hits = -3, j; unsigned long z_max = OUL, z_min = ULONG_MAX, name_id = OUL; unsigned int ptr = mw_selected_objects;
BM_EDGE ^edge = NULL; long old_data; if (mi_show_solid) { // RenderWare picking. if (m_pick.type == rwNAPICKOBJECT) { // No clump was picked. if (add_hit_to_list) return; else clear_selection_set 0 ;
41 APPENDIX E return; else if (m_pick. type == rwPICKCLUMP) { // Some clump was picked; process it. picked_clump = m_pick. object . clump. clump; vert = m_pick. object .clump. wcpoint; RwTranslateMatrix (RwScratchMatrix () , CREAL (md_x_trans) , CREAL (md_y_trans) , CREAL (0.0) , rwREPLACE) ;
RwTransf ormMatrix (RwScratchMatrix ( ) , md_rot_matrix, rwPRECONCAT) ;
RwTrans la teMat rix ( RwScrat chMat rix ( ) , CREAL ( - m_part_centroid.X() ) , CREAL (- m_part_centroid. Y ( ) ) ,
CREAL(- m_part_centroid .7,0) , rwPRECONCAT) ;
RwMatrix4d inverse = RwCreateMatrix 0 ;
RwInvertMatrix(RwScratchMatrix() , inverse) ; RwTransformPoint (_vert, inverse) ; RwDestroyMatrix(inverse) ; parent_clump = RwGetClumpParent (picked_clump) ; parent_tag = RwGetClumpTag(parent_clump) ; clump_tag = RwGetClumpTag(picked_clump) ; if (parent_tag == 1) {
// The body of a face/bendline/forming was picked. key = (clump_tag%10000) ♦lOOOOO + clump_tag; if (m_selection_set.find(key, NULL)) { m_selection_set .remove (key, _old_data) ; // Remove clump from selection set (toggle) . if (old_data) delete (BV_SELECT_DATA ) old_data; return;
} else { i f ( ! a d d _ h i t _ t o _ l i s t ) clear_selection_set () ; // Remove everything else in selection set,
BV_SELECT_DATA data = newBV_SELECT_DATA; data->key = key; data->edge = NULL; (data->world_pt) = BM_POINT(vert.x, vert.y, vert.z); m_se lect ion_se t . insert ( key , (long)data) ; // insert this key and data. return;
// Now an edge was picked. key = (parent_tag%10000) lOOOOO + clump_tag;
42 APPENDIX E if (clump_tag) {
// Safety check; we expect clump_tag to be non-zero, if (m_selection_set.find(key, NULL)) { m_selection_set.remove (key, _old_data) ; // Remove clump from selection set (toggle) . if(old_data) delete (BV_SELECT_D TA ♦)old_data; else { i f ( ! a d d _ h i t _ t o _ l i s t ) clear_selection_set 0 ; // Remove everything else in selection set . e d g e map_list_name_to_bm_edge (parent_tag, clump_tag) ;
BV_SELECT_DATA Λdata = new BV_SELECT_DATA; data->key = key; data->edge = edge; (data->world_pt) = BM_POINT (vert.x, vert.y, vert.z) ; m_selection_set . insert (key , (long)data); // insert this key and data.
}
else { / / OpenGL
Picking. num_hits = glRenderMode (GL_RENDER) ; // The number of hits. if (num_hits == -1) { // Selection buffer has overflowed.
AfxMessageBox("Too many entities selected; change view and try again. ") ; return;
} if (num_hits == 0) {
// No hit; only a miss. if (add_hit_to_list) return; else clear_selection_set () ; return;
}
// Process the hits : find the edge with LOWEST z value of all the edges picked. for(j=0; j < num__hits; ++j) { ptr += 1; // Skip the 1st element bee. it will always be 1, if ( (unsigned long) (ptr) < (unsigned long) z_min) { z_min = (unsigned long) (ptr) ;
43 APPENDIX E ptr += 2; name id = (long) (+ptr) ; ++ptr;
} else ptr += 3;
}
// Find the bm edge corresp. to the name and add it to the selection set. if (name_id) { //
Something was selected. if (m_selection_set . find(name_id, NULL)) { m_selection_set .remove (name_id, _old_data) ; // Remove edge from selection set (toggle) . if(old data) delete (BV SELECT DATA *)old data;
} el_e { if ( ! add_hit__to_list) clear_selection_set () ; // First, we massage the name_id into the format RenderWare picking uses. parent_tag = name_id/100000 + 10000; clump_tag = name_id%100000; edge = map_list_name_to_bm_edge (parent_tag, clump_tag) ;
BV_SELECT_DATA data - new BV_SELECT_DATA; data->key = key; data->edge = edge; (data->world_pt) = BM_POINT(0.0, 0.0, 0.0); m_selection_set.insert (name_id, (long)data) ; // insert this key and data.
} } return;
// This function maps a RenderWare parent clump and child clump pair to the
// Bend Model edge which the child clump represents. The pointer to the edge is returned.
// This function only needs to deal with "real" edges, ie. trivial bendlines and
// formings are filtered out by process_hits_records itself.
BM_EDGE CBendCADViewPart : : ap_list_name_to_bm_edge (long parent_tag, long clump_tag)
44 APPENDIX E long three_d_name, three_d_type, loop nam , edge name, count = 0, offset = 0;
BM_3D_B0DY three_d_body - NULL; BM_2D_B0DY two_d_body = NULL; BM_LOOP loop = NULL; BM_EDGE edge = NULL; BM_PART part = NULL; BM_TOPOLOGY topology = NULL;
CBendCADDoc^ pDoc = GetDocument () ; ASSERT VALID(pDoc) ; part = pDoc->get_part () ; if ( ! part) return NULL; // Note: we do not expect part to be NULL at this stage, topology = part->get_topology() ; if ( ! topology) return NULL; three_d_name = parent_tag%10000; three_d_body = topology->map_id_into_pointer (three_d_name) ; // Now we have a pointer to the face/bendline to which the picked edge belongs . three_d_type = three_d_body->get_type () ; if (three_d_type == BM_ENTITY_TYPE_FACE) offset = 30000; if (three_d_type == BM_ENTITY_TYPE_BENDLINE) offset = 60000; if (three_d_type == BM_ENTITY_TYPE_FORMING) offset = 90000; loop__name = (clump_tag - offset) /100; edge_name = (clump_tag - offset) %100; if (loop_name == 0) return NULL; // This should never be the case.
// Now have the edge_name-th edge in the loop_name-th loop of the face/bendline/forming.
// Now we have the face/bendline to which the edge belongs, if (mi_show_3d) two_d_body = three_d_body->get_3D_version() ; else two_d_body = three_d_body->get_flat 0 ; if ( ! two_d_body) return NULL; if (loop_name == 1) loop = two_d_body->get_bloop 0 ; else { count - 1; for (loop = two_d_body->get_first_hole O ; loop; loop = (BM_L00P ) loop->next () ) { if ( ! loop) return NULL; ++count;
45 APPENDIX E if (count == loop_name) break;
} }
// Now we have the loop to which the edge belongs, if (loop == NULL) return NULL; // A trivial bendline was picked, count = 0; for(edge = loop->get_first_edge () ; edge; edge = (BM_EDGE ♦) edge->next () ) { if ( ! edge) break;
++count; if (count == edge_name) break;
}
// Now we have the edge itself. return edge;
Figure imgf000427_0001
1st three-d-body . if (three_d_name > (ml_num_bendlines + ml_num_f aces) ) return NULL; // The thing drawn is a forming , if ( ! loop_name) return NULL ; // The thing drawn is a trivial bendline . if (three_d_name > ml_num_bendlines) { // The three_d_body is a face . for (three_d_body = part - >get_f ace_list ( ) ; three_d_body; three_d_body = (BM_3D_B0DY ) three_d_body->next () ) { if(! three_d_body) return NULL; ++count; if ((ml num bendlines + count) == three d name) break;
-lse { // The three_d_body is a bendline. for(three_d_body = part->get_bendline_list () ; three_d_body; t hree_d_body = ( BM 3 D BODY
) three_d_body- >next ( ) ) { if ( ! three_d_body) return NULL; ++count ; if (count == three_d name) break ;
46 APPENDIX E
} // Now we have the face/bendline to which the edge belongs . if (mi_show_3d) two_d_body = three_d_body->get_3D_version() ; else two_d_body = three_d_body->get_flat () ,- if ( ! two_d_body) return NULL; if (loop_name == 1) loop = two_d_body->get_bloop 0 ; else { count = 1; for(loop = two_d_body->get_first_hole () ; loop; loop = (BM_LOOP ♦) loop->next 0 ) { if ( ! loop) return NULL;
++count; if (count == loop_name) break;
} // Now we have the loop to which the edge belongs. count = 0; for(edge = loop->get_first_edge () ; edge; edge = (BM_EDGE ♦) edge->next () ) { if ( ! edge) break;
++count; if (count == edge_name) break;
} return edge; */
// This function returns the number of items currently in the selection set. long CBendCADViewPart::get number of selected items (void)
{ return m selection set. list size () ;
}
/ This allows other classes to get the selection set. The selected items are passed back in the array selected_items__array; it is the responsibility of the user to ensure that this array is of sufficient size. An array of size num_requested^2 is exactly sufficient. The function will pass back up to num_requested items, if that many are available.
47 APPENDIX E The return value is the number of items actually passed back.
The format of the returned items in the array is as follows: selected_items_array[2^i -2] contains the OpenGL Display List id of the edge drawn, and selected_items_array[2^i -1] contains the Bend Model pointer to that edge. Eg. selected_items_array[0] , selected_items_array[1] correspond to the
1st item in the selection set, etc. all the way up to array[2Λnum_requested -2] , array[2^num_requested -1] for the num_requested-th item in the selection set.
If the edge pointer is NULL, you need to do some further processing:
Let N be the OpenGl display list id of this edge; N is of type long.
Case A) : If N/10000 > (num_bendlines_in_part + num_faces_in_part) then the user has picked the N - (num_bendlines + num_faces) forming.
Eg: num_bendlines = 4, num_faces = 3, num_formings = 5, N/10000 = 9, edge pointer is NULL. Then user has picked the 2nd forming.
Case B) : If (N%10000) /100 == 0 (ie. the hundredths digit of N is zero) then the user has picked the center line of a trivial (unbent) bendline.
The bendline is the (N/10000) -th bendline. Eg: N/10000 = 3, edge pointer is NULL, (N%10000) /100 == 0. The user has picked the 3rd bendline, which happens to be unbent. (In case you were wondering, this part is guaranteed to have at least 3 bendlines) . */ long CBendCADViewPart : : get_selected_items ( long num_requested, long selected_items_array) if ( selected_items_array == NULL) return 0 ; l ong i = m_s e l e c t i on_s e t . d i sp l ay ( num_re que s t e d , selected_items_array) ; return i ;
}
48 APPENDIX E
// This allows others to clear the selection set. void CBendCADViewPart ::clear selection set (void)
{ int size = m_selection_set . list_size () ; long array = new long [ (size<<l) + 1] ; m_selection_set .display(size, array) ; for(long i=0; i < size; ++i) { if (array[ (i<<l) + 1]) delete (BV_SELECT_DATA ) array[ (i<<l)
+ 1] ;
} m_selection_set .remove () ; delete [] array; }
// This function writes a RenderWare matrix's rotation part into an array[16] , which can be used by
// OpenGL. int CBendCADViewPart: :convert_rw_matrix_to_gl_array(RwMatrix4d
♦rw matrix, double Λarray)
{ "
RwReal rw_array[4] [4] , test; test = RwGetMatrixElements (rw_matrix, rw_array) ; if ( ! test) return 0; int i , j ; for ( i=0 ; i < 4 ; ++i) { for (j =0 ; j < 4 ; ++j ) array [4 Λi + j ] = rw_array [i] [j ] ;
} array [15] = 1 . 0 ; array[3] = array[7] = array[11] - 0.0; return 1;
// This function allows you to set the drawing mode: show_solid =
1 for solid, 0 for wireframe.
// This function assumes that the part has not changed. void CBendCADViewPart ::set drawing mode (int show solid)
{ " if (show_solid) OnViewShaded() ; else OnViewWireframe () ; }
// This function allows you to set the current view of the part show_3d = 1 for 3d version,
49 APPENDIX E
// 0 for flat.
// This function assumes that the part has not changed, void CBendCADViewPart::set current view(int show 3d)
{ if(show_3d) OnShow3d( else OnShowFlat 0 ;
// This allows you to set both solid/wireframe (show_solid = 0/1) and flat/3d_version (show_3d = 0/1) .
// If flat is asked for, the picture shown is top view, zoomed-all.
// If 3d is asked for and flat is currently in view, the picture shown is 3d, isometric, zoomed-all.
// If 3d is asked for and 3d is already currently in view, the view volume is not changed.
// If part_has_changed is not zero, re-faceting is done. void CBendCADViewPart::set_drawing_view_mode(int show_solid, int show 3d, int part_has_changed)
{ int show_3d_isometric = 0; if ( ( ! mi show 3d) __ (show 3d) show 3d isometric = 1; mi_show_solid = show_solid; mi show 3d = show 3d; int i;
BM_PART part = NULL;
CBendCADDoc^ pDoc = GetDocument 0 ;
ASSERT_VALID(pDoc) ; part = pDoc->get_part () ; if(! part) { mi_part_is_up_to_date = 0; return;
} mi_part_is_up_to_date = 1; if (part_has_changed) { compute_part_centroid(part, 0, _m_flat_part_centroid) ; / / Compute 3d and flat part centroids. compute_part__centroid(part, 1, &m_3d_part_centroid) ;
Figure imgf000431_0001
50 APPENDIX E
RwRemoveClumpFromScene (m_base_clump) ; m_base_clump = m_3d_base_clump; RwAddClumpToScene (m_scene, m_base_clump) ,- else { if (part_has_changed | | ( ! m_flat_base_clump) ) { i = acet_part_rw(part, _m_flat_base_clump, mi_show_3d, md_part_color) ; if ( (! i) | | ( ! m 3d base clump) ) return;
}
RwRemoveClumpFromScene (m__base_clump) ; m_base_clump = m_flat_base_clump;
RwAddClumpToScene (m scene, m base clump) ;
} else { // OpenGl stuff. i = prepare_display_list (part, mi_show_3d, 1, 0, 1, 1,
0;
;
Figure imgf000432_0001
mi__bbox_is_up_to_date = 0; if (mi_show_3d) m_part_centroid = m_3d_part_centroid; else m_part_centroid = m_flat_part_centroid; if (part_has_changed) { ml_num_faces = part->get_number_of_faces () ; ml_num_bendlines = part->get_number_of_bendlines () ; ml_num_formings = part->get_number_of_formings 0 ; ml_last_function_chosen = RETURN_FROM_DIALOG_MODE; if (show_3d_isometric) { OnZoomAll () ; return; }
51 APPENDIX E if ( ! mi_show_3d) OnViewTop () ; return; } return;
52 APPENDIX F
nι/11111/ιιιιιnιιιuιιιιιιιιιιnιnιιιι/ιιιnιιιιιιιιιιιιιιι ι 1ι/ Example of BMAPI auto dimensioning main include file / u/ // with comments //
// //
// Copyright 1996 AmadaSoft America, Inc. //
// //
////////////////////////////////////////////////////////////// /*
General Notes :
***************
- Auto-Dimensioning package assumes that the part is already up to date, ie. the 3D version is already computed. It takes the current 3D-version of the part and uses it.
- As of 04/02/96 Auto-Dimensioning only generates dimensions for the 3D version of the part.
- As of 04/02/96 Auto-Dimensioning assumes that the part is shown with thickness (ie. it assumes that we are not showing just one side of the sheetmetal) .
Overview :
***************
Auto-Dimension draws two kinds of things :
- flange length for every bendline
- bendline information for every bendline
Bendline information is drawn in a small info-box that points to the bendline it is associated with.
The only problem with drawing those info-boxes is whether the bendline is visible, where to draw the info-box (ie. where on the screen to draw it so that it looks good and does not interfere with other stuff, for instance, does not overlap with other things) , how to associate it with the bendline. This stuff is relatively straightforward.
Flange length of the bendline is the largest outside distance between the bendline and an adjacent flange on the side of the bendline. Note that a bendline can have at most two adjacent APPENDIX F flanges, so we have to draw flange length with respect to both adjacent flanges.
In practice, flange length is drawn (as a distance) between points that we call dimension points.
There are two types of dimension points. The first type is bendline dimension points.
Since flange length is the (largest outside) distance between a bendline and an adjacent flange, these dimension points that are on the side of the bendline are called bendline dimension points.
Their location is defined solely by the bendline.
Note that (at least in the current version of the BendModel/BendCAD) one bendline can have exactly two bendline dimension points with respect to each of the adjacent flanges.
Each of the two bendline dimension points corresponds to the two ends of a bendline.
Also note that usually these pairs of bendline dimension points with respect to both adjacent flanges match. That is - bendline dimension points with respect to adjacent flange A (there are two bendline dimension points with respect to A) and the same as bendline dimension points with respect to another adjacent flange B. That is, they are physically not the same, but they have the same values.
Bendline dimension points are calculated using intersection approximation (if the bend angle is no more that 90 degrees) or tangent approximation (if the bend angle is more than 90 degrees) .
If the bend angle is not more than 90 degrees, pairs of bendline dimension points with respect both adjacent flanges are the same, because the intersection approximation points match.
The other type of dimension points is flange dimension points. They are points on the flange adjacent to the bendline, on the side of the bendline, that are the farthest away from the bendline. Assuming the flange is correct (ie. non-empty) there is at least one flange dimension point. However, theoretically there is no upper bound on the number of flange dimension points.
Note an important point. If a flange A, adjacent to a bendline B, and also is adjacent to a bendline C at its farthest point (ie. at the flange dimension point with respect to B) , the flange dimension points of B with respect to A are really the same bendline dimension points of C with respect to A (ok, assuming that bendlines B and C are parallel, otherwise things get tricky and it is not true any more) .
Flange dimension points are computed at the corners of the flange, because dimension have to be drawn at the side of the flange. APPENDIX F
This is how the Auto-Dimension works : **************************************
It is divided into two different tasks. One is computing all the dimension points (both bendline dimension points and flange dimension points) . At this stage we compute all dimension points at which flange length could be drawn. Potentially this could be done only once and provided that the part does not change we can reuse this information later every time auto-dimensions have to be drawn. (However, the part usually does change - when the user rotates the part, then the viewer actually rotates the part, not the camera (which is usually done) . So the 3D coordinates of the part change. However, we could base our calculations on Wflat of the part which is not affected by this kind of change, but fortunately computing all dimension points is pretty fast and it seems to be ok to recompute dimension points all the time. I just want to point out that we could, if needed, save some time by precomputing these dimension points once and then later reusing them) .
Once we have computed all dimension points, we can draw dimensions. But first we have to figure out which of the dimension points are visible and which are not. When we have a wireframe picture, it is pretty easy. A dimension points is visible if it is in the view window. Checking this is very fast. If we have a solid (shaded) picture things are harder because flanges closer to the viewer usually block the view of some other flanges farther away, blocking some dimension points as well. So we need to do some kind of hidden line removal.
Once we have determined which dimension points are visible, it could be that a flange length can be drawn in a number of different ways, in which case we have to pick one, hopefully the best one. Note : to show flange length, we need a bendline dimension points and a flange dimension point. One heuristic is to pick bendline-flange-dimension points which are closest to the viewer and for which the side-ways distance is the smallest.
Once we have picked dimension points for all bendlines we can draw dimensions.
Main data structures of Auto-Dimension : ****************************************
There are three classes of objects used. BM_AUT0_DIMENSION
3 APPENDIX F
is the top-level Auto-Dimension object and is usully part of a BendCAD document along with a BM_PART.
It contains a pointer to a BM_PART for which auto-dimensions are being drawn, as well as document, view and device context pointers. It also contains high-level information like the view window size, number of bendlines, a list of BM_AD_bendline objects, etc .
In the future (today is 04/03/96) it should store information about the pen and brush properties, like line color, line width, font size, etc.
BM AD bendline
stores all auto-dimension information related to one BM_BENDLINE.
It has built-in two bendline dimension points with respect to each of the adjacent flanges.
It also has pointers to lists of flange dimension points with respect to each of the adjacent flanges.
BM AD dim corner
is a dimension point (either bendline or flange) . Dimension points can have either 1 or 3 BM_POINTs.
One important member of a dimension points is opening direction. It points in the direction in which the acutual dimension with respect to this dimension points has to be drawn. Also, this is the direction from which this dimension point is visible.
Every dimension points also has a flag indicating whether it is visible or not. If it is visible, it stores screen coodinates of all of its BM POINTS. */
#ifndef BMAPI_AUTO_DIM_HXX_INCLUDED #define BMAPI_AUTO_DIM_HXX_INCLUDED
// include some BMAPI include files
#include "POINT.HXX" #include "VECTOR.HXX" #include "LINE.HXX" #include "PLANE.HXX" #include "CYLINDER.HXX" #include "2D BODY.HXX" APPENDIX F
#include "3D_BODY.HXX" #include "BEND_OP.HXX" #include "BENDLINE.HXX" #include "PART.HXX"
// include header for mesh to determine clear regions for drawing
#ifndef AD_MESH_H
#include "AD_Mesh.h" #endif
// some BendCAD classes class CBendCADDoc ; class CBendCADViewPart ;
// Auto-Dimension classes class BM_AD_dim_corner ; class BM_AD_bendline ; class BM_AUTO_DIMENSION ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Auto-Dimension constants.
********** ********** ********** ********** **********
********** ********** ********** ********** */
// dimension line length is 30 pixels
#define PIXELS_PER_DIMENSION_LINE 30.0
// arrow angle is 30 degrees
//#define ARROW_ANGLE 0.524
// arrow length is 15 pixels
//#define PIXELS_PER__ARROW 15.0
// this is the distance tolerance used in Auto-Dimension #define AUTODIM_DISTANCE_TOLERANCE 0.001
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Objects of this type represent a dimension point in the part for which a dimension could be drawn.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/ class BM AD dim corner { - - - APPENDIX F friend BM_AUTO_DIMENSION ; friend BM_AD_bendline ;
/* ********** ********** ********** ********** **********
********** ********** ********** **********
All data members are private.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/ private :
// Auto-Dimension BM_AD_bendline object that owns this dimension point
//
BM_AD_bendline bend ;
// this is the 3D-body in the part that has to be visible (actually some points on this
// body have to be visible) in order for this dimension point to be drawable.
// note : this is used only when we are in solid mode.
//
// usually, for bend-dim points, this points to the bendline, and for flange-dim points
// points to the flange.
// However, when this dimension point contains only one point (point p) , some special
// considerations come into effect.
//
BM_3D_BODY body_required_visible ;
// this variable is used only when we are drawing in a solid mode.
// if TRUE, we will ignore this dimension point as if it was not visible.
//
// in solid mode we will be using this heuristic in order to save time.
// when two bendlines are using equivalent flange-dimension points for (potentially)
// displaying flange-length, we will only compute the visibility information only
// for the bendline (of these two bendlines) which has the larger idx.
//
// this is initialized to FALSE, and set to TRUE only after all other dim-point computations // have been done. APPENDIX F
// int ignore_in_solid_mode ;
// Sometimes when the point in the part for which we want to draw dimensions is a
// bendline (either inside or outside) such that the radius and thickness both are not 0,
// we have to draw two short lines (as in the picture following) that connect the
// outsides of adjacent flanges. HoweVer, sometimes (when both radius and thickness
// are 0, or the point is just an outside edge of a face) we need only one point.
// To capture these two cases, we either compute three points between which the
// short line have to be drawn, or just one point (in which case no short lines are needed) .
/ /
// P2
/ / 1
1 \l/
/ / P bbFFFFFFFFFFFF
// 1 1 bbb F
/ / two 1 bbb F
/ / short - > i b F
/ / lines 1 b bbFFFFFFFFFFFF
// lb b
// |b b
/ / b b
// b b
/ / p FFFFFFFF
/ / F F
// F F
/ / F F
// F F
/ / F F
//
// this is the number of points that we have computed here, it is either 1 or 3.
// int num_of points ;
//
// p is always the centerpoint to which the dimension arrow should be connected to
// (actually it is what we call a 'dimension-line-extension' ) .
// if we have computed more than 1 point, pi and p2 are the side-points.
//
// IMPORTANT : pi is on the plane of the adjacent body for which the flange length is being drawn. // APPENDIX F
// Note : point p is always computed.
//
BM_P0INT p, pi, p2 ;
// this variable is used when this dimension point is a flange dimension point, and
// the edge in the flange, for which this flange dimension points was computed,
// is adjacent to a bendline. adj_bendline points to that bendline.
//
// this is used to avoid drawing some flange-length twice, for example, in this picture
//
// B2-
//
//
//
//
// Bl
//
// we want to draw dimensions for face A in the middle only once. That means that if
// we draw flange length for bendline Bl with respect to A, we should not draw it for
// bendline B2 (with respect to A) .
//
BM_BENDLINE adj_bendline ;
// this vector points to the direction in which the dimension should be drawn for this dim-point.
//
// IMPORTANT : this vector should be normalized.
//
BM_VECTOR opening_direction ;
//
// if this is TRUE, we can reverse the opening_direction if we need.
// sometimes the dimension point correcponds to an extreme point of an arc. in that case it does
// not matter on which side we are drawing the dimension arc (ie. we can reverse the opening direction) .
// int can_reverse_opening dir ;
//
// these variable are used only when this dimension point is actually drawn.
// pos_len is the length of the dimension-line-extension drawn in the direction of the opening vector.
// neg_len is the length of the dimension-line-extension drawn
8 APPENDIX F in the direction opposite to // the opening vector.
//
// they are initially set to 0 when the visibility of this point is computed.
//
// the purpose is that we can use them to avoid redrawing the same extension line, if several
// other dimension points need it.
//
// Note : as of 04/02/96 these points are not used. KK.
// double pos_len, neg_len ;
// +1, this dimension point is visible and the dimension arc can be drawn for this point .
// 0, this dimension point is not visible.
// -1, we don't know if this dimension points is visible.
//
// initially we set this to -1 and use it to compute the visibility information on demand
// (ie. only when we want to know if this points is visible. sometimes we don't care) .
// int visible ;
// these are the actual view window coordinates of all 3 points.
// int screen_x, screen_xl, screen_x2 ; int screen_y, screen_yl, screen_y2 ;
//
// this is the z-buffer value of the point p when rendered.
// double z_buf_value ;
// this is used to construct lists of dim-points.
//
BM_AD_dim_corner next ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Private member-functions . Used only by Auto-Dimension. ********** ********** ********** ********** **********
********** ********** ********** **********
*/
// this function computes the visibility of this dimension point.
// it handles wireframe and solid modes separately. APPENDIX F
// this function checks strict visibility. void compute_visibility(CBendCADViewPart *vιe ) ;
// this function will draw the dim-point in the given device context .
// this is really just a debug function.
// void draw_with_dim_line (CBendCADViewPart view, CDC dc, double object_space_per_pixel) ;
// given a bendline dimension point and a list of flange dimension points, this function
// returns TRUE iff there is a way to display the flange-length-dimension using these points
// (ie. there is a pair of points that is visible) or FALSE if not.
// If it returns TRUE, it also returns the best flange dimension point ; as well as
// the distance between the bendline dimension point p and the best flange dimension point p,
// with respect to the bendline dimension point.
//
// Note that the best distance returned could be negative since it is the k-factor with respect
// to the bendline-dimension-opening-direction-vector.
// Remember : bendline-dimension-opening-direction-vector should be normalized.
//
// this function checks strict visibility.
// friend int compute_best_dim_pair(CBendCADViewPart ♦view, BM_AD_dim_corner bend_dim_point,
BM_AD_dim_corner flange_dim_list , double object_space_per_pixel,
// OUTPUT parameters double best_distance / distance of the best flange-dim points found /,
BM_AD_dim corner ♦♦best_flange_dim_point /♦ the best flange-dim points *J) ;
// this function draws one flange length dimension, the first argument is a bendline dimension point,
// the second is a flange dimension point.
// this function might allow cases where some dimension extension line is a little-bit
// outside the view window.
// however, endpoints of the dimension arrow have to be within the view window.
//
10 APPENDIX F friend void draw_dim_point (BM_AD_dim_corner bend_dim_point , BM_AD_dim_corner +f lange_dim_point ,
CBendCADVi ewPart vi ew , CDC dc , doub l e obj ect_space_per_pixel) ;
/*
* * * * * *** * * *** * * *** * * * * ** * ***** ***** * ** * * **** * * ****
** ******** ********** ********** **********
Public member-functions.
********** ********** ********** ********** **********
********** ********** ********** **********
*/ public :
BM_AD_dim_corner(void) ;
// this constructor is for creating a dimension point that has only one point (point p) in it .
//
BM_AD_dim_corner (BM_POINT const- p, BM_AD_bendline bend,
BM_3D_BODY body_required_visible,
BM_VECTOR constSc opening_direction, int reverse_bit, BM_AD_dim_corner ♦♦prev, BM_BENDLINE adj_bendline) ;
// this constructor is for creating a dimension point that has 3 points in it.
//
BM_AD_dim_corner(BM_P0INT const- p, BM_POINT const- pi, BM_POINT const_ p2,
BM_AD_bendline bend, BM_3D_BODY body_required_visible, BM_VECTOR const- opening_direction, int reverse_bit, BM_AD_dim_corner ♦♦prev, BM_BENDLINE adj^endline) ;
// to assign one dimension point to another dimension point // it copies contents exactly, not sure if it is a very useful function.
// void operator= (BM_AD_dim_corner const Sc) ;
// this function will return TRUE iff the given point is, for the purpose of drawing dimensions,
// the same as this point.
// Two dimension points points are equivalent iff the point p of one of them is on the
// line defined by the line (point p, opening direction) of the other dimension point,
// and their opening directions match.
//
// here we depend on the fact that opening vectors are
11 APPENDIX F normalized.
// it returns 2 iff both points p match, otherwise 1. int operator== (BM_AD_dim_corner const- another_dim_point) ;
} ;
/*
********** ********** ********** ********** **********
* ******** ********** ********** **********
Objects of this class represent auto-dimensioning data associated with one bendline.
Basic AD operation with respect to a bendline is drawing adjacent flange length.
Technical notes :
- the opening direction vectors of bendline dimension points and flange dimension points are not correlated. That means that when drawing, you should check for two point having the same opening direction.
- algorithm : First we compute all bendline dimension points for all bendlines. Then we compute all flange dimension points for all bendlines. The reason is that when we compute flange dimension points, some edges in the flange and adjacent to some other bendline.
In order to create a flange dimension point, we need some vectors about the other bendline
(ie. bendlines should already be computed) .
If we compute all bendline dimensions first, we can take these vectors from the bendline dimension points of some other BM_AD_bendline structure.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/ class BM AD bendline
{ ~ " friend BM_AUTO_DI ENSION ; friend BM_AD_dim_corner ;
/*
********** ********** ********** ********** **********
12 APPENDIX F
********** ********** ********** **********
All data members are private.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/ private :
/*
********** ********** ********** ********** **********
********** ********** ********** **********
These data members are set by the constructor.
********** ********** ********** ********** **********
********** ********** ********** **********
*/
// information stored in this BM_AD_bendline object refers to this bendline.
// ie . this dimension point is drawn to show the flange length of this bendline.
//
BM_BENDLINE bend ;
// this object belongs to this Auto-Dimension object.
//
BM_AUTO_DIMENSION parent ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
These data members are computed when the bendline dimension point data structures are computed - in BM_AD_bendline: :compute_BM_AD_bendline ( ... ) . ********** ********** ********** ********** ********** ********** ********** ********** **********
*/
// if FALSE, this data for this object has not been yet computed, or the computation failed.
// this means that this object will always be ignored, no matter what.
// this can be set to TRUE only by BM_AD_bendline: :compute_BM_AD_bendline (...) .
// int data_ alid ;
// number of adjacent bodies for which we have to draw dimensions, either 0, 1 or 2. // int num_of_adjacent__bodies ;
// every bendline is adjacent to at most two bodies.
13 APPENDIX F
// either of these can be NULL, you should always check for that.
// adj_bodyl is the adjacent body that has the smaller idx. // adj_body2 is the adjacent body that has the larger idx.
//
BM_3D_BODY adj Dodyl ;
BM_3D_BODY adj_body2 ;
// this is the flange length with respect to each of the adjacent bodies
// double fll ; double fl2 ;
/* These parameters are computed some time durmg the process and are needed later, so for performance reasons we store them so that we don't have to recompute them later.
Each of them is a vector pointing towards the adjacent body (from the bendline) and is on a plane tangent to end end-point of the bend-arc touching the adjacent body.
*/
BM_VECTOR side_vectorl ; BM_VECTOR side_vector2 ;
/*
These are some of the main data structures. For each adjacent body, we have two points, one for each endpoint (ie. left and right) of the bendline.
These points specify the points at which dimensions for flange length can be drawn at the bendline (ie. on the side of the bendline) .
Remark : currently (04/02/96) we consider exactly two possible points for drawing dimensions at every bendline. These two points are two extreme points of the bendline in the direction of the bendline centerline.
Note : these are called bendline dimension points of the bendline.
Note : these points are always computed, even if adj_bodyl and adj_body2 are NULL. */
BM_AD_dim_corner bend_bodyl_point_left, bend_bodyl_j)oint_right
14 APPENDIX F
BM_AD_dim_corner bend_body2_point_left, bend_body2_point_right ;
// these variables indicate whether the left (right) bendline dimension points
// with respect to adj -bodyl and adj-body2 are respectively equivalent.
// these points should be computed right after bend_bodyl_point_left, bend_bodyl_point_right,
// bend_body2_point_left, bend_body2_point_right are computed.
//
// if 0, they are not equivalent.
// if 2, they are equivalent, and points p match. // if 1, they are equivalent, but points p don't match (ie. on the same line, but some distance apart) .
//
// for us, equivalence value 2 is the only really useful one, because in that case we can
// trust that when one is visible, the other is too, without checking, in that case they have the
// same screen coordinates as well.
//
// note the same means not the same pointers, but the contents are equivalent.
// int bodyl2_left_the_same ; int bodyl2_right_the_same ;
/*
Here are two lists of dimension points. One with respect to adj -bodyl, the other with respect to adj-body2. Both lists contain points that are flange-length dimensions points.
Note : these are called flange dimension points of the bendline.
*/
BM_AD_dim_corner bodyl_points ; BM_AD_dim_corner body2_points ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
These data members are used when dimensions are being drawn. ********** ********** ********** ********** ********** ********** ********** ********** **********
*/
// if this is TRUE, this bendline structure should be ignored for the purpose of drawing dimensions.
15 APPENDIX F
// this is usually used when we have a simultaneous bendline. in that case we have to draw
// dimensions for only one of them, the rest should be ignored.
// int ignore ;
// if TRUE, the adjacent body already has its flange length drawn.
// if the value is 2, this bendline drew the flange dimension with respect to the adj body.
// if the value is 1, some other bendline drew the flange dimension with respect to the adj body.
// int bodyl_drawn ; int body2_drawn ;
// when we draw flange length for adjacent bodies, we will memorize the point at which the
// dimensions were drawn.
// actually the dimensions are always drawn between two points - one at the bendline,
// the other at the farthest point on the adjacent body (ie. bendline dimension point and
// flange dimension point) .
//
// the reason we need to memorize these points is that sometimes the flange-length-dimension
// with respect to one bendline is also the flange-length dimension with respect to the
// other bendline. in that case we want to avoid drawing the same thing twice.
//
// the first two points are bendline dimension points.
// other two are flange dimension points.
//
// reason #2 : when we draw bendline dimensions with respect to adj-bodyl and adj-body2,
// it depends whether the bend angle is acute or not. if the bend angle is not more than
// 90 degrees, then most likely we will be able to use the same dimension-point at the bendline
// to draw both flange length's. However, if the bend angle is more than 90 degrees, we will
// be using the tangent-dimension-point at the bendline and these points are different for
// each adjacent body. In general, we want to know, before we draw a dimension-point at a
// bendline, if we can use any of the dimension-points already
16 APPENDIX F drawn at this bendline.
//
// note these points do not have to part of this AD_bendline structure.
//
BM_AD_dim_corner ♦drawn_bend_dim_pointl ;
BM_AD_dim_corner ♦drawn_bend_dim_point2 ;
BM_AD_dim_corner drawn_flange_dim_pointl ;
BM_AD_dim_corner Λdrawn_flange_dim_point2 ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Private member-functions .
********** ********** ********** ********** **********
********** ********** ********** **********
*/
// This function computes bendline dimension points of this
BM_AD_bendline structure.
// Note that bend-dimension points will always be computed, even if adj_bodyl and adj_body2
// are NULL.
// int compute_BM_AD_bendline(void) ;
// This function computes flange dimensions points of this BM_AD bendline structure
7/ with respect to one adjacent body.
// int compute_BM_AD_flange_points (BM_3D_BODY adj_body) ;
// This function computes the visibility of all bendline dimension points of the bendline.
// note the the visibility of bend-dimension points with respect to adj-bodyl is always
// computed, even if adj_bodyl pointer is NULL.
// This is needed for drawing bendline info-boxes.
// void compute_bendline_dim_points_visibility(void) ;
// this function computes which dimension points are best to draw flange length for this bendline.
//
// this function does it strictly for one bendline.
// void compute_dim_points_to_display_indiv(
BM_AD_bendline best_AD_bendline [2] / best AD_bendline structure so far ♦/,
BM_AD_dim_corner bodies_bend_flange [6] /♦ 0,1 is bend-dim points; 3,4 is flange-dim points; , 5 is flange lists ♦/,
17 APPENDIX F double distance and z [4] /♦ 0,1 is distance; 3,4 is z-buf
7)
// this function does it for a given bendline, taking into account simultaneous bendlines.
// this function uses the previous function.
// void compute_dim_points_to_display (void) ;
// this function draws flange length dimensions for this bendline .
/ / i t us e s the inf ormat ion comput e d by compute_dim_points_to_display ( ) function .
// void draw_dimension_points (void) ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Public member-functions.
********** ********** ********** ********** **********
********** ********** ********** ********** */ public :
// some trivial constructors, destructors.
BM_AD_bendline(BM_AUTO_DIMENSION owner, BM_BENDLINE ♦bendline) ;
~BM AD bendline (void) ;
} ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
This object can be used to create automatic dimensions for a part.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/ class BM AUTO DIMENSION
{ " " friend BM_AD_dim_corner ; friend BM_AD_bendline ,-
/*
********** ********** ********** ********** **********
********** ********** ********** **********
18 APPENDIX F
All data members are private.
********** ********** ********** ********** **********
********** ********** ********** ********** */ private :
// this is the document to which this auto-dim object is attached to.
// also, this is where we get the part.
//
CBendCADDoc doc ;
// view in which we draw the dimensions.
// usually the view attached to the document.
//
CBendCADViewPart ^view ; int view_size_x, view_size_y ;
// device context in which we draw the dimensions.
//
CDC +dc ;
// this is the part for which we will create dimensions.
//
BM_PART part ;
// is TRUE iff 3D view is being displayed, FALSE if flat.
// int view_type ;
// half of the metal thickness
// double half_metal__thickness ;
// if TRUE, we need to recompute auto dimension bendline and point data structures
// int dirty ;
// number of bendlines in the part
// int num_of_bendlines ;
// this is an array of bendlines for which flange length has to be drawn.
//
BM_AD_bendline ♦♦bends ;
// this is the distance in object space that gets mapped into
19 APPENDIX F one pixel on the screen.
// we use it to draw lines of fixed pixel length (in that case object-space length varies) .
// double object_space_per_pixel ;
// if this variable is TRUE, it will set the flag which will trigger
// auto-dimensions to be drawn to FALSE in the view class, once dimensions are drawn.
// however, once it is done, this variable will be set to
FALSE automatically.
// int reset_view_to_false_once_drawn ;
// every time we construct new dim-point data structures, we set this to FALSE.
// when points which can be ignored in solid mode have been computed, we set it to TRUE.
// int points_to_ignore_in_solid_computed ;
// pointer to mesh for determining clear areas of the screen to draw dimension info
//
CAutoDimRgnMesh ♦pMesh;
// region to keep track of dirty screen areas
//
CRgnΛ pDirtyRegion; public:
// Booleans for the show state of dimension info
//
BOOL m_bShowFlangeDim;
BOOL m_bShowBendDim;
BOOL m_bShowPartDim;
// COLORREFs for drawing dimensions
//
COLORREF m_crFlange;
COLORREF m_crBend;
COLORREF m_crPart;
// pointers to fonts
//
CFont^ m_pFlangeFont;
CFont^ m_pBendFont;
CFont^ m pPartFont;
20 APPENDIX F
// line and arrow parameters
// int m_nLineStyle; int m_nLineWeight; // in pixels int m nArrowStyle; int m_nArrowAngle; // in degrees int m_nArrowLength; // in pixels
/ *
********** ********** ********** ********** **********
********** ********** ********** **********
Private member-functions.
********** ********** ********** ********** **********
********** ********** ********** ********** */ private :
// This function is used to propagate the effects of drawing a flange length for a given bendline,
// to account for the fact that the flange dimension point is adjacent to the given adj-body.
// it returns TRUE iff the adj -bend will be marked as drawn as well with respect to the given flange.
// int compute_effects_flange_length_drawn(BM_BENDLINE ♦bendline,
BM_3D_BODY adj_body / flange length with respect to this body are being drawn /,
BM_AD_dim_corner bend_dim_point / bend dim point for bendline /,
BM_AD_dim_corner *flange_dim_point / flange dim points for bendline /,
BM_BENDLINE +adj_bend / flange dim points is adjacent to this bendline /) ;
// this function returns a pointer to the BM_AD_bendline structure that contains data
// about the given bendline.
//
BM_AD_bendline get_AD_bend_structure (BM_BENDLINE ♦bendline)
II this function will return TRUE iff adj_bend has a flange-dimension point with respect to the
// given flange, that is adjacent to the given bendline.
//
// a handy function.
// int check_two_bendlines_adjacent_to_same_flange (BM_BENDLINE
21 APPENDIX F
♦bendline,
BM_3D_BODY ♦flange, BM_BENDLINE adj Dend) ;
// just a debug function
// void test_draw(void) ;
// Check if we can ignore some points in solid mode.
//
// in solid mode we will be using this heuristic in order to save time.
// when two bendlines are using equivalent flange-dimension points for (potentially)
// displaying flange-length, we will only compute the visibility information only
// for the bendline (of these two bendlines) which has the higher idx.
// void compute_points_to_ignore_in_solid(void) ;
// this function draws a box with bendline data for every bendline.
// void draw_bendline_data (CDC pdc) ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
Public member-functions.
********** ********** ********** ********** **********
********** ********** ********** ********** */ public :
BM_AUTO_DIMENSION(CBendCADDoc BendCAD_doc) ; -BM_AUTO_DIMENSION(void) ;
// this function returns a (p->p2) vector for a given bendline with respect to a given adj-body.
// It also computes a line between the p2 points of the bend dimension points of the adjacent bendline
// with respect to this flange.
//
BM_VECT0R const- compute_bend_direction vector (BM BENDLINE bendline, BM_3D_B0DY adjjsody, ~
BM_LINE p2_line) ;
// destroy the contents of this Auto-Dimensions object,
22 APPENDIX F
// void delete_contents (void) ;
// To set a new part. This updates the view class pointer as well .
// void set_part (BM_PART *ne j)art) ;
// to force AD to recompute the dimension points.
// inline void invalidate (void) { dirty = 1 ; }
// get current view type when points were computed
// inline int get_view_type (void) const { return view_type ; }
// this function will build auto dimension bendline and point data structures.
//
// This is the main function for computing dimension points.
// int compute_auto_dimension_data (void) ;
// draw flange dimension data
// void draw_dim_point (BM_AD_dim_corner bend_dim_point, BM_AD_dim_corner flange_dim_point,
CBendCADViewPart view, CDC ♦dc, double object_space_per_pixel) ;
// to draw part dimensions in this device context
// int draw_auto_dimensions (CDC target_dc) ;
// Used with draw_auto_dimensions to construct a geometric pen // with user-defined styles. This is necessary to draw patterned thick lines.
//
CPen^ create_auto_dim_pen(CPen# pPen, int nLineStyle, int nLineWeight, COLORREF cr) ;
// this will enable us to draw part dimension only once
// inline void disable_view_dimensions_flag_next_time (void) { reset view to false once drawn = 1 ; } } ; ~ " " " ""
#endif // BMAPI AUTO DIM HXX INCLUDED
23 APPENDIX G u i mi /mnu it mum tin nun i iuuiiiiiiiiiiiii ι 1ι/ Example of auto dimension drawing functions. These '/J/, // functions assume that the dimension points are // // already computed. //
/ /// Copyright 1996 AmadaSoft America, Inc. ////,
'/l 11111111 It 1111111111111 II 111111111 It 11111 II HI 111111111 II 111
I*
Functions to compute dimension points are in AD_P0INTS.CPP.
First we need to detect which dimension points are visible, which are not.
Then we have to decide how to draw flange length dimensions.
*/
#include "stdafx.h"
#include "BendCAD.h"
#include "BendCADDoc.h"
#include "BendCADViewPart.h"
#include "BCAD_CTXT.HXX"
#include "AD_Arrow.h"
#include "AUTODIM.HXX"
/*
********** ********** ********** ********** **********
********** ********** ********** **********
BM_AD_dim_corner class stuff .
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
/*
This function computes the visibility of a dimension point . */ void BM_AD_dim_corner: :compute_visibility(CBendCADViewPart view) int i, j, k ,- double z_buf ;
// by default, the points is not visible visible = 0 ; if (num_of_points < l) return ;
// note : when in wireframe mode, we don't have to check if
1 APPENDIX G points pi and p2 actually
// map into the same bendline/flange points, in solid mode we need to check.
// check if we have solid or wireframe mode. if (view->get_drawing_mode() ) goto solid_picture ;
/*
Wireframe, don't check if the 3D-body to which this dimension points is actually in the foreground.
In wireframe mode we assume that everything in the view window is visible.
*/
// get visibility data i = view->map_point_to_closest_edge(p, _screen_x, Scscreen_y, _z_buf_value, NULL) ; if (! i) return ; if (num_of_points > 1) { i = view->map_point_to_closest_edge(pi, _screen_xl, Scscreen_yl, _z_buf, NULL) ; if ( ! i) return ; i = view->map_point_to_closest_edge(p2, _screen_x2, _screen_y2, _z_buf, NULL) ; if ( ! i) return ; }
// process visibility data pos_len = neg_len = 0.0 ; visible = 1 ; return ;
/*
Part shown in solid mode.
*/ solid__picture :
// here we keep pointers to 3D-bodies that have to be visible.
BM_3D_B0DY ♦visiblejoodies [4] ; visible_bodies [0] = body_required_visible ; if (body_required_visible->is(BM_ENTITY_TYPE_BENDLINE) ) { visible_bodies [1] = ( ( ( BM_BENDL INE ) body_required_visible) ->get_adj_list () ) ->f ind_lowest_id_adj_body ( ) visible_bodies [2 ] = ( ( ( BM_BENDL INE ) body_required_visible) ->get_adj_list 0 ) ->f ind_second_lowest_id_ad j_body() ,- visible bodies [3] = NULL ;
} else visible bodies [1] = NULL ; APPENDIX G
// handle cases when there is just one point differently from when there are 3 points.
// if there is only 1 point, we have a complete paper-part - thickness and radius both 0.
// in that case there is really no bendline. we have to check any of the adjacent bodies. if (num_of_points < 2) {
// if this is a bend-dimension point, the body_required__visible pointer should point to the
// adjacent body with respect to this dimension point is computed. i = view->is_3d_body_near_point (p, visible_bodies, _i, _screen_x, _screen_y, _z_buf_value) ; if ( ! i) return ; else {
/*
SOLID HEURISTIC : this here is a new version of handling solid mode. first we check if all three points p, pi and p2 are in the view window. if true, we compute the centerpoint of the side profile of the bend arc, and check if the bendline at this point is actually visible.
*/ i = view->map_point_to_closest_edge (p, _screen_x, _screen_y, Scz_buf_value, NULL) ; if ( ! i) return ;
/*
SOLID HEURISTIC : if the opening direction cannot be reversed, check if it is not pointing away if ( ! can_reverse_opening_dir) {
BM_P0INT p_opening_direction(p + opening_direction) t__edge (p_opening_direction, + 0.001)) return ; // here pointing away
Figure imgf000459_0001
// check if points pi and p2 are in the view window as well. APPENDIX G i - view->map_point_to_closest_edge (pi, _screen__xl, _screen_yl, _z_buf, NULL) ; if ( ! i) return ; i = view->map_point_to_closest_edg (p , _screen_x2, _screen_y2, _z_buf, NULL) ; if ( ! i) return ;
BM_VECTOR v__ppl(p,pl) ;
BM_VECTOR v_pp2(p,p2) ;
BM_POINT p_center ; double angle_alpha = (v_ppl A v_pp2)/2.0 , if (angle_alpha < PI_over_2) {
BM_VECTOR v_plp2(0.5Λ (p2 - pi)) ;
BM_POINT temp p(pi + v_plp2) ;
BM_VECTOR v_tip(p,temp_ ) ; double z - (v_ppl.Len() ) /cos (angle_alpha) ; double y = z+sin(angle_alpha) ; v _ t i p . s e t _ l e n g t h ( ( z - y ) + (bend->parent) ->half_metal_thickness) ; center - p + v_tip .; - else p_center = p ; ody_near_point (p_center, visible_bodies ,
Figure imgf000460_0001
;
/*
This the old version of handling solid mode. Here we check if the point p is in the view window, and if points pi and p2 have the underlying 3D-body visible.
// if we have 3 points, the point p is not on any 3D-body. threfore we only check if it is
// in the view window. view->is_3d_body_near_point (p, NULL, _i, Scscreen_x, _screen_y, 5cZ_buf_val_e) ; if ( ! i) return ;
// points pi and p2 have to be on the 3D-body. i = view->is_3d__body_near_point (pi, visible_bodies, Scvisibility_count , _screen_xl, _screen_yl, _z_buf) ; if ( ! i) return ; i = view->is_3d__body _near_point (p2, visible_bodies, _visibility_count , _screen_x2, _screen_y2 , Scz_buf) ; if (1 i) return ,- */
}
// process visibility data
4 APPENDIX G pos_len = neg_len = 0.0 visible = 1 ;
/* this function will draw the dim-point in the given device context . this is really just a debug function.
*/ void BM_AD_dim_corne : :draw_with_dim_line (CBendCADViewPart ♦view, CDC ♦dc, double object_space_per_pixel)
{ int i, j ; double x ; static POINT points [3] ;
BOOL res ;
// if this point is not known to be visible, return. if (visible < 1) return ; if (num_of_points < 1) return ; points [1] . x = screen_x ; points [1] . y = screen_y ;
// draw dimension line
BM_POINT p_dim_line (p + (PIXELS_PER_DIMENSION_LINE obj ect_space_per_j?ixel) opening_direction) ; view- >map_point_to_closest_edge (p_dim_line , _i , _j , SX, NULL)
; points [2] .x = i ; points [2] .y = j ,- if (can_reverse_opening_dir) { p_dim_line p + (-PIXELS_PER_DIMENSION_LINE object_space_per__pixel) opening_direction ; view->map_point_to_closest_edge (p_dim_line, Sci, Scj , SX, NULL) ; points [1] .x - i ; points [1] .y = j ; res = dc->Polyline(points + 1, 2) ; points [1] .x = screen_x ; points [1] -y = screen_y ; else res = dc->Polyline (points + 1, 2) ; if (num_of_points < 2) return ; points [0] . x = screen_xl ; points [0] . y = screen_yl ; APPENDIX G points [2] .x = screen_x2 ; points [2] . y = screen_y2 ; res = dc->Polyline (points, 3)
This function draws one flange length dimension.
The first argument is a bendline dimension point, the second is a flange dimension point. */ void BM_AUTO_DIMENSION : : draw_dim_point (BM_AD_dim_corner
♦bend_dim_point , BM_AD_dim_corner f lange_dim_point ,
CBendCADViewPart view, CDC dc, double object space_per_pixel)
{ int i, j ; double x, y, z, dotp, half_dim_.line
BOOL res ;
// points with screen coordinates. Windows type, static POINT points [3] ;
// these variable store the coordinates of the dim- line-extension endpoints double bend_end_x, flange_end_x ;
BM_POINT bend_end_p, flange_end_p ;
BM_VECTOR end_v (bend_dim_point->opening_direction) ;
// these variables store arrow head endpoints BM_POINT bend_arrow_ , f lange_arrow_p ;
// compute the dimension line extension
BM_VECTOR v( (f lange_dim_point->p) - (bend_dim_point->p) ) ; x = v % (bend_dim__point->opening_direction) ; if (fabs(x) > AUTODIM_DISTANCE_TOLERANCE) { // we have to extend at least one dimension line half_dim_line = (PIXELS_PER_DIMENSION_LINE object_space_per_pixel) /2.0 ;
// here we will first compute extension lines, then the arrow, and then the dimension points themselves if (x < 0.0) {
// here we assume that for bendline, we cannot reverse the opening direction.
// it must be that the flange-dim points has a valid opening direction in the same direction
// as the bend-dim point. // APPENDIX G
// arrow point is to the right of the bend-dim point . bend_arrow_p = (bend_dim_point - >p ) + half_dim_line^end_v ; if (! view->map_point_to_closest_edge (bend_arrow_p, Sci, Scj, Scy, NULL)) return ; points [0] . x = i ; points [0] .y - j ; f lange_arrow_p = (f lange_dim_point->p) + (-x + half dim_line) *end_v ; i f ( ! view->map_point_to_closest_edge (flange_arrow_p, &i , Scj, Scy, NULL)) return ; points [1] .x = i ; points [1] .y = j ;
Figure imgf000463_0001
APPENDIX G bend_end_x = z + half_dim_line ; flange_end_x = -x - half_dim_line ; bend_end_p = bend_dim_point - >p bend_end_xAend_v ; flange_end_p = f lange_dim_point->p f lange_end_x^end_v goto begin to draw } " ~ try_other_direction : i f ( d o t p > 0 . 0 J | f lange_dim_point- >can_reverse_opening_dir) {
// arrow point is to the right of the flange-dim point. bend_arrow_p = (bend_dim_point->p) + (x + half dim_line) end_v ; i f ( ! view->map_point_to_closest_edge (bend_arrow_p, Sci, _j , Scy, NULL)) return ; points [0] .x = i ; points [0] -y = j ; f lange_arrow_p = (f lange_dim_jpoint->p) + half dim line#end_v ; i f ( ! view->map_point_to_closest_edge (f lange_arrow_p, _i, Scj, Scy, NULL)) return ; points [1] .x = i ; points [1] .y = j ; half_dim_line = 2.0 ; bend_end_x = x + half_dim_line ; flange_end_x = half_dim_line ; bend_end_p - bend_dim_point - >p + bend_end_xΛ end_v flange_end_p = flange_dim_jpoint->p flange_end_x^end_v ;
} else return ; // failure, cannot draw because opening direction don't match or not visible.
else { // no need to extend dimension lines
// check the direction of opening vector if (end_v % (flange_dim_point->opening_direction) < 0.0) if (! flange_dim_point->can_reverse_opening_dir) end v.reverse() ;
} bend_end_x - flange_end_x = (PIXELS_PER_DIMENSION_LINE APPENDIX G object_space_per_pixel) ; bend_end_p = bend_dim_point->p + bend_end_xΛend_v ; flange_end_p = f lange_dim_jpoint->p + f lange_end_xAend_v bend_arrow_p = bend_dim_point->p + (bend_end_x/2.0) end v
; f lange_arrow_p = f 1 ange_d im_po i n t - >p +
( f 1 ange_end_x/ 2.0 ) ♦ end_v ;
// compute arrow endpoints if (! view->map_point_to_closest_edge (bend_arrow_p, Sci, Scj , Scy, NULL) ) return ; points [0] .x = i ; points [0] .y = j ; if ( ! view->map_point_to_closest_edge (f lange_arrow_p, Sci, &j , _y, NULL) ) return ; points [1] .x = i ; points [1] .y = j ;
begin_to_draw :
/*
Draw arrow.
*/
// draw arrow line, points[0] is the bend-dim-points side of the arrow. res = dc->Polyline(points, 2) ;
// draw arrows
BM_VECTOR v_arrow(flange_arrow_p - bend_arrow_p) ; x = v_arrow.Len() ; // this is the real flange length
// change to solid pen for arrow heads
CPen* pArrowPen = new C P e n ( P S _ S O L I D ,
BCAD_context . m_nFlangeLineWeight , BCAD_context . _crFlange ) ; CPen^ pOldPen = dc->SelectObject (pArrowPen) ;
// compute arrow head at bend side CAutoDimArrow arrowBend(
CPoint(points [0] .x, oints[0] .y) ,
CPoint(points[1] .x,points[1] .y) ,
BCAD_context.m_nArrowAngle,
BCAD_context.m_nArrowLength ) ; arrowBend.DrawHead(dc) ;
// compute arrow head at flange side CAutoDimArrow arrowFlange( APPENDIX G
CPoint (points [1] .x,points [1] .y) , CPoint (points [0] .x,points [0] .y) , BCAD_context .m_nArrowAngle, BCAD_context .m_nArrowLength ) ; arrowFlange.DrawHead(dc) ; dc->SelectObject (pOldPen) ; delete pArrowPen;
// write flange length on the screen int center_x = (points [0] .x + points [1] .x) >> 1 ; int center_y = (points [0] .y + points [1] .y) >> 1 ; int font_height = 21 ; double dx = (double) (points [l] .x - points [0] .x) ,- double dy = (double) (points [1] .y - points [0] .y) ; if (fabs(dx) > AUTODIM_DISTANCE_TOLERANCE) ( if (dy/dx > 0.0) center y -= font_height ;
} center_x += 3 ; // move the beginning to the right so that it won't overlap the arrow line.
CString str; str.Format ("%6.4f" ,x) ;
CSize sizeTextExtent = dc->GetTextExtent (str) ; if (pDirtyRegion != NULL)
{
CPoint pntText (center_x, center_y) ;
CRect rectText (pntText, sizeTextExtent) ; if ( !pDirtyRegion->RectInRegion(_rectText) ) dc->TextOut (center_x, center_y, str) ;
CRgn rgn; rgn.CreateRectRgn(center_x, center_y, center__x + sizeTextExtent.ex, center_y + sizeTextExtent.cy) ; pDirtyRegion->CombineRgn(pDirtyRegion, _rgn, RGN OR) ;
} else
{ pDirtyRegion = new CRgn() ; pDirtyRegion->CreateRectRgn(center_x, center_y, center_x + sizeTextExtent .ex, center_y + sizeTextExtent.cy) ; dc->TextOut (center x, center y, str) ; }
/* if necessary draw pl,p2 for bend-dim-points
*/
10 APPENDIX G points [1] .x = bend_dim_point->screen_x ; points [1] .y = bend_dim_point->screen_y ; if (bend_dim_point->num_of_points > 1) { points [0] .x = bend_dim_point->screen_xl points [0] .y = bend_dim_point->screen_yl points [2] .x = bend_dim_j?oint->screen_x2 points [2] .y = bend_dim_point->screen_y2 res = dc->Polyline (points, 3) ;
} // draw dimension line extension view->map_point_to_closest_edge (bend_end_ , Sci, Scj , _x, NULL) points [2] .x = i ; points [2] .y = j ; res = dc->Polyline (points + 1, 2) ;
if necessary draw pl,p2 for flange-dim-points points [1] .x = flange_dim_point-.>screen_x ; points [1] .y = flange_dim_j?oint->screen_y ; if (flange_dim__point->num_of_points > 1) { points [0] .x = flange_dim_point->screen_xl points [0] .y = flange_dim_point->screen_yl points [2] .x = flange_dim_point->screen_x2 points [2] .y = flange_dim_point->screen_y2 res = dc->Polyline (points, 3) ;
} // draw dimension line extension view->map_point_to_closest__edge (flange_end_p, Sci , Scj SLX ,
NULL) points [2] .x = i ; points [2] .y = j ; res = dc->Polyline (points + 1, 2)
/* given a bendline dimension point and a list of flange dimension points, this function returns TRUE iff there is a way to display flange-length-dimension using these points
(ie. everything is visible) or FALSE if not.
If it returns TRUE, it also returns the best flange dimension point ; as well as the distance between the bendline dimension point p and the best flange dimension point p, with respect to the bendline dimension point.
Note that the best distance returned could be negative since
11 APPENDIX G it is the k-factor with respect to the bendline-dimension-opening-direction-vector.
Remember : bendline-dimension-opening-direction-vector should be normalized.
Note : right now this function assumes that the dimension-extension-lines are drawn in the following way : one dimension-extension-line is unit-length, and the other is as long as necessary to reach the first one. Ie. this function draws the dimension arrow rigth next to one of the dimension points. Ie. it does not try to draw the dimension arrow at some point in the middle of the line between the two dimension points.
Note : in this function we will not directly check if dim points are visible (we will call another function to do that) . we will check that some dimension-extension-lines be within the viewing window.
Note : in this function we check points where dimension arrows would go. We require that they be strictly within the viewing area.
Note : in this function we really use approximated locations, ie. as a heuristic. */ int compute_best_dim_pair(CBendCADViewPart view, BM_AD_dim_corner ♦bend_dim_jpoint,
BM_AD_di m_c o rne r f 1 ang e_di m_ l i s t , double object space_per_pixel, ll OUTPUT parameters double ♦best_distance / distance of the best flange-dim points found /,
BM_AD_dim_corner ♦♦best_flange_dim_point / the best flange-dim points /)
{
BM_VECTOR v ;
BM_POINT dim_arrow_point ; int i, j , k ; double x, y, dotp ;
// if the bendline dimension point is not known to be visible, return FALSE.
// otherwise we might be wasting our time, if (bend_dim_ oint->visible < 1) return 0 ;
// scan the list of flange dimension points BM_AD_dim_corner temp_point, best_fdp = NULL ;
12 APPENDIX G double best_distance_so_far ; for (temp_point = f lange_dim_list ; temp_point ,- temp_point = temp_point->next) { if (! temp_j?oint->visible) continue ;
/*
SOLID HEURISTIC : in solid mode we will be using this heuristic in order to save time. when two bendlines are using equivalent flange-dimension points for (potentially) displaying flange-length, we will only compute the visibility information only for the bendline (of these two bendlines) which has the higher idx.
*/ i f ( v i e w - > g e t _d r a w i n g_m o d e ( ) _ _ temp_point->ignore_in_solid_mode) continue ;
// compute a vector from bend-dim-p to flange-dim-p v = (temp_point->p) - (bend_dim_point->p) ; x = v % (bend_dim_point->opening_direction) ;
// check that opening directions are valid.
// idea : if both vectors points in opposite directions are we cannot reverse them,
// we cannot use these two dimension points to draw dimensions. dotp = (bend_dim_point->opening_direction) % (temp_point->opening_direction) ; if (dotp < 0.0 cSc ! temp_point->can_reverse_opening_dir ScSc. ! bend_dim_point->can_reverse__opening_dir) continue ;
// check that the point where the dimension arrow would go is in the view area
/ / n o t e : w e w i l l u s e half-of-the-minimal-extension-length as the unit separating // zero and non-zero length extension lines. if (fabs(x) > AUTODIM_DISTANCE_TOLERANCE) { k = 0 ; // if k is TRUE at the end, we can draw the dimension arrow point if (x < 0.0) {
// note : add space for a line segment where we will draw the arrow
//
// check if the directions agree. // we check this first, because it would give us a smaller distance. if (dotp > 0.0) { dim_arrow_point = (temp_point->p) +
13 APPENDIX G
(-x) (bend_dim_point->opening_direction) ; i f
(view->map_point_to_closest_edge (dim_arrow__point, _i, Scj, Scy, NULL) ) k = 1 ;
} // check that the extension of the bend-dim-line is visible.
// in that case the opening direction of the flange-dime-line does not matter. i f ( ! k - Sc bend_dim_point->can_reverse_opening_dir) { dim_arrow_point = (bend_dim_point->p) + (x) ♦ (bend_dim__point->opening_direction) ; i f
(view->map_point_to_closest_edge (dim_arrow_point, _i, Scj, Scy, NULL) ) k = 1 ;
else { // x > 0.0
// note -. add space for a line segment where we will draw the arrow.
//
// check if the extension line is visible.
// we check this first, because it would give us a smaller distance. i f ( d o t p < 0 . 0 | | temp_point->can_reverse_opening_dir) { dim_arrow_point = (temp_point->p) + (-x) ♦ (bend_dim_point->opening_direction) ; i f
(view->map_point_to_closest_edge (diτn_arrow_point, Sci, Scj, _y, NULL) ) k = 1 ;
} // otherwise check if the directions agree. if Ok) { dim_arrow_point = (bend_dim_point->p) + (x) ♦ (bend_dim__point->opening_direction) ; i f
(view->map_jpoint_to_closest_edge(dim_arrow_jpoint, _i, Scj , Scy, NULL) ) k = 1 ;
if (!k) continue ; // cannot draw the dimension arrow point
}
// check if visibility information is already computed. // if not, compute it. if flange dimension points not visible, continue.
14 APPENDIX G if (temp_point->visible < 0) { temp_point->compute_visibility(view) ; if (! temp_point->visible) continue ;
// check if this new distance is the best distance if (best_fdp) { if (fabs(best_distance_so_far) > fabs(x)) { best_fdp = temp_point ; best_distance_so_far = x ;
else { best_fdp = temp__point ; best distance so far = x ;
} "
// check if we are done.
// if we have a point with a distance 0, we are done since we cannot find a better point. if (best_fdp Sc_ fabs (best_distance_so_far) <= AUTODIM DISTANCE TOLERANCE) break ; " } if (best_fdp) {
♦best_distance = best_distance_so_far ; ♦best_flange_dim_point = best_fdp ; return 1 ; } return 0 ;
}
/ *
********** ********** ********** ********** **********
********** ********** ********** **********
BM_AD_bendline class stuff.
********** ********** ********** ********** **********
********** ********** ********** ********** */
/*
This function computes the visibility of all bendline dimension points of the bendline.
Note : in order to save some time, we will check if bodyl,2 left (right) points are equivalent.
*/
15 APPENDIX G void BM_AD_bendline: :compute_bendline_dim_points_visibility(void) CBendCADViewPart view = parent->view ;
// here we always compute the visibility of adj-bodyl bend-dimension points,
// even though we don't check if adj_bodyl pointer is NULL or not,
// because we might want to know the visibility even if they don't exist.
//
// in practice this should not be a problem because almost always there are two
// adjacent bodies.
// bend_bodyl_point_left.compute_visibility(view) ; bend_bodyl__point_right.compute_visibility(view) ; if (adj_body2) { if (2 == bodyl2_left_the_same) { if (bend_body2_point_lef t .visible bend_bodyl_point_left .visible) {
// note we are switching points bend_body 2 _po i n t _ 1 e f t . s c r e e n_x bend_bodyl_jpoint_left . screen_x ; be nd_body 2 _po in t _1 e f t . s c r e e n_y bend_bodyl_point_lef t . screen_y ; bend_body2_point_left . screen_xl bend_bodyl_jpoint_lef t . screen_x2 ; bend_body2_point lef t . screen_yl bend_bodyl_jpoint_lef t . screen_y2 ; bend_body2_point lef t . screen_x2 = bend_bodyl_point_lef t . screen_xl ; bend_body2_point lef t . screen_y2 bend_bodyl_point_lef t . screen_yl ; bend_body2_point_lef t . z_buf_value bend bodyl point left . z buf value ;
»' ' " " else bend_body2_point_lef t .compute_visibility (view) ; if (2 == bodyl2_right_the_same) { if ( bend_body 2_point_r ight . vi s ible bend_bodyl_point_right .visible) {
// note we are switching points bend_body2_point_right . screen_x = bend_bodyl_point_right . screen_x ; bend_body2_point_right . screen_y bend_bodyl_point_right . screen_y ; bend_body2_point_right . screen_xl
16 APPENDIX G bend_bodyl_point_right . screen_x2 bend_body 2_ p] oint_right . screen_yl bend_bodyl_point_right . screen_y2 bend_body 2_ p] oint_right . screen_x2 bend_bodyl_point_right . screen_xl ; bend_body2_point_right . screen_y2 bend_bodyl_point_right . screen_yl ; bend_body2_point_right . z_buf _value bend_bodyl_point_right . z_buf _value ;
else bend_body2_point_right .compute_visibility (view) ;
// else adj_body2 is NULL and there is nothing to compute
}
/*
This function tries to find the best way for drawing flange length for one bendline.
This function does it strictly for one bendline.
Important : it only determines which way would be the best way, but it does not decide if AD will really do it that way. Now will it do any updating other data structures.
In short, it does not change any of the AD data structures.
Note : no checks in the beginning.
Idea : in this function we use a heuristic to assign values for different bend-flange-dim points combinations. Eventually we choose the best combination.
The heuristic we use is a combination of the distance between the bend and flange dim points, plus the distance of the bend-dim point from the view screen.
A practical trick : first we check if the best known distance values is already 0. If yes, we will try to find a best match for another bend-dim points only if this new bend-dim points has a better z-buf value.
Note : after testing 4 parts, I found that this gives just a very slight improvement, may-be 5-10%. KK. */ void BM_AD_bendline: :compute_dim__points_to_display_indiv(
BM_AD_bendline best_AD_bendline [2] / best AD_bendline structure so far ♦/,
BM_AD_dim_corner bodies_bend_flange [6] /♦ 0,1 is bend-dim points; 3,4 is flange-dim points; 4,5 is flange lists ♦/,
17 APPENDIX G double distance and z [4] / 0,1 is distance; 3,4 is z-buf ♦/)
{ " "
BM_AD_dim_corner bes^fdp ; double best_distance ;
// check adjacent bodyl if (adj_bodyl ScSc ! (bodyl_drawn) ) {
// check if we already have a distance 0 bend- flange-dim points, if yes, go in only if the
// new bend-dim points has a strictly better z-buf value, if ((NULL == best_AD_bendline [0] ) |j distance_and_z [2] > (bend_bodyl_point_lef t . z_buf _value + AUTODIM_DISTANCE_TOLERANCE) | | distance_and_z [0] > AUTODIM_DISTANCE_TOLERANCE) { i f ( comp t e_bes t_dim_pair (parent- >view,
_bend_bodyl_point_lef t , bodyl_points , parent ->object_space_per_pixel, _best_distance, Scbest_fdp) ) { best_distance = fabs (best_distance) ; // check if the new point is better if (best_AD_bendline [0] ) {
// heuristic : if the sum of the z-buf value and distance is smaller i f ( ( b e s t _ d i s t a n c e + bend_bodyl_point_left . z_buf_value) < (distance_and_z [0] + distance_and_z [2] ) ) { best_AD_bendline [0] = this ; bodies_bend_f lange [0] =
_bend_bodyl_point_left ; bodies_bend_f lange [2] = best_fdp ; bodies_bend_f lange [4] = bodyl__points distance_and_z [0] = best_distance ; d i s t a n c e _a n d_ z [ 2 ] bend_bodyl_point_lef t . z_buf_value ;
else { best_AD_bendline [0] = this ; bodi e s_be nd_f l ange [ 0 ] _bend_bodyl_point_lef t ; bodies_bend_flange [2] = best_fdp ; bodies_bend_flange [4] = bodyl_points ; distance_and_z [0] = best_distance ; d i s t a n c e _ a n d _ z [ 2 ] = bend bodyl point lef t . z buf value ;
// check if we already have a distance 0 bend-flange-dim
18 APPENDIX G points, if yes, go in only if the
// new bend-dim points has a strictly better z-buf value. i f ( d i s t a n c e _ a n d _ z [ 2 ] >
(bend_bodyl_point_right.z_buf_ alue + AUTODIM_DISTANCE_TOLERANCE)
| j (NULL == best_AD_bendline [0] ) j | distance_and_z [0] >
AUTOD I M_D I S TANCE_TOLERANCE ) { if (compute_best_dim_pair (parent->view,
_bend_bodyl_point_right , bodyl_points , parent - >ob j ect_space_per__pixel , &cbest_distance , _best_fdp) ) { best_distance = fabs (best_distance) ; // check if the new point is better if (best_AD_bendline[0] ) {
// heuristic : if the sum of the z-buf value and distance is smaller i f ( ( b e s t _ d i s t a n c e + bend_bodyl_point_right . z_buf_value) < (distance_and_z [0] + distance_and_z [2] ) ) { best_AD_bendline [0] = this ; bod i-e s_bend_f lange [ 0]
_bend_bodyl_point_right bodies_bend_flange [2] = best_fdp ; bodies bend flange [4] = bodyl_points distance_and_z [0] = best_distance d i s t a n c e _ a n d _ z [ 2 ] bend_bodyl_j?oint_right . z_buf_value ;
}
} else ( best_AD_bendline [0] = this ; bo d i e s_ben d_ f l ang e [ 0 ] Scbend_bodyl_point_right ; bodies_bend_flange [2] = best_fdp ; bodies_bend_flange [4] = bodyl__points distance_and_z [0] = best_distance ; d i s t a n c e _ a n d _ z [ 2 ] bend_bodyl_point_right . z_buf _value ;
}
}
}
// check adjacent body2 if (adj_body2 ScSc ! (body2_drawn) ) {
// check if we already have a distance 0 bend-flange-dim points, if yes, go in only if the
// new bend-dim points has a strictly better z-buf value. if ( (NULL == best_AD_bendline[l] ) | | distance and z [3] >
(bend_body2_point_left.z_buf_value +AUTODIM_DISTANCE TOLERANCE) I I I I
19 APPENDIX G distance_and_z [1] > AUTODIM_DISTANCE_TOLERANCE) { if ( comput e_best_dim_pair (parent ->view,
Scbend_body2_point_lef t , body2_points , parent- >object_space_jρer_pixel , _best_di stance , _best_f dp) ) { best_distance = f abs (best_distance) ; // check if the new point is better if (best_AD_bendline[l] ) {
// heuristic : if the sum of the z-buf value and distance is smaller i f ( ( b e s t _ d i s t a n c e + bend_body2_point_lef t . z_buf_value) < (distance_and_z [1] + distance_and_z [3] ) ) { best_AD_bendline [1] = this ; bodies_bend_f lange [ 1 ] Scbend_body2_point_left ; bodies_bend_f lange [3] = best_fdp ; bodies_bend_f lange [5] = body2_points distance_and_z [1] = best_distance ; d i s t a n c e _ a n d _ z [ 3 ] bend_body2_point_lef t . z_buf_value ;
else { best_AD_bendline [1] = this ; b o d i e s _b e n d_ f l a ng e [ l ] Scbend_body2_point_left ; bodies_bend_flange[3] = best_fdp ; bodies_bend_flange[5] = body2_points ; distance_and_z [1] = best_distance ; d i s t a n c e _ a n d _ z [ 3 ] - bend_body2_point_lef t . z_buf _value ;
// check if we already have a distance 0 bend- flange -dim points, if yes, go in only if the
// new bend-dim points has a strictly better z-buf value. i f ( d i s t a n c e _ a n d _ z [ 3 ] >
(bend_body2_point_right . z_buf _value + AUTODIM_DISTANCE_TOLERANCE)
| | (NULL == best_AD_bendline [1] ) | | distance_and_z [1] >
AUTODIM_DISTANCE_TOLERANCE) { i f ( comput e_be s t_dim_pair (parent ->view,
_bend_body2_point_right , body2_point s , parent - >ob j ect_space_per_pixel , 5cbest_distance , Scbest_fdp) ) { best_distance = f abs (best_distance) ; // check if the new point is better
20 APPENDIX G 44 r
if (best_AD_bendline [1] ) {
// heuristic : if the sum of the z-buf value and distance is smaller i f ( ( b e s t _ d i s t a n c e + bend_body2_point_right . z_buf_value) < (distance_and_z [1] + distance_and_z [3] ) ) { best_AD_bendline [1] = this ; bodies_bend_f lange [1]
Scbend_body2_point_right bodies_bend_f lange [3] = best_fdp ; bodies_bend_f lange [5] = body2_points distance_and_z [1] = best_distance d i s t a n c e _ a n d_ z [ 3 ] bend body2_point right . z buf value ;
- - } else { best_AD_bendline [1] = this ; bod i e s_^b end_f l ange [ l ] Scbend_body2__point_right ,- bodies_bend_flange [3] = best_fdp ; bodies_bend_flange [5] = body2_points ; distance_and_z [1] = best_distance ; d i s t a n c e _ a n d _ z [ 3 ] bend body2 point right . z buf value ;
}
/*
This function determines how to draw flange length for a bendline.
It is different from the previous function in that using the previous function as a subroutine, it decides how to draw flange length dimensions for a bendline, as well as updates all data structures accordingly.
Also, it takes into account simultaneous bendlines. */ void BM_AD_bendline: :compute_dim_points_to_display(void)
// qualification check if (NULL == bend) return ;
21 APPENDIX G
BM_AD_bendline bl ; long i ;
// these variable store the bendline dimension data that will be used later to draw
// 0,1 is with respect to adj -bodyl; 2,3 is with respect to adj -body2
BM_AD_dim_corner bodies_bend_flange_list [6] ; // 0,1 is bend-dim points; 2,3 is flange-dim points; 4,5 is flange lists double distance_and_z [4] ; // 0,1 is distance; 2,3 is z-buf
// this is the bendline for which we will be drawing the dimensions.
// this is trivial when there is no simultaneous bendlines.
BM_AD_bendline ♦best_AD_bendline [2] = { NULL, NULL } ;
/*
Compute the best way for drawing flange length. Take simultaneous bendlines into account.
*/
// these variables are for handling simultaneous bendline property things.
BM_BEND_PROPERTY prop ; BM_LINKED_LIST_NODE prop_list ; DBM_ARRAY bendlines ; BM_BENDLINE Λbnd ; long size, this_bend_seen = 0 ; for (prop_list = bend->get_properties () ; prop_list ; prop_list = prop_list->next () ) { prop = (BM_BEND_PROPERTY ) prop_list->get_obj 0 ; if (prop- >is (BM_TYPE_BEND_SIMULTANEOUS) ) { bendlines = (DBM_ARRAY ) prop->get_bendlines 0 ; size = bendlines->get_size () ; for (i = 0 ; i < size ; i++) {
// get a bendline in the bend property object if (NULL == (bnd = (BM_BENDLINE ) bendlines->get (i) ) ) continue ; bl = parent->get_AD_bend_structure (bnd) ; if (NULL == bl) continue ; if (bl == this) this bend_seen = 1 ; if (1 bl->data_valid~] I bl->ignore) continue ; // compute how to draw flange length dimensions for this one bendline. bl- >compute_dim_points_to_display_indiv (best_AD_bendline, bodies bend flange list, distance and z) ;
if ( ! this_bend_seen) { // make sure this bendline gets processed
22 APPENDIX G bl = parent->get_AD_bend_strueture(bend) ; if (bl -Sc bl->data_valid ScSc ! bl->ignore) { bl- >compute_dim_points_to_display_indiv (best_AD_bendline, bodies bend flange list, distance_and_z) ;
' )' ] ~
I*
Mark all other bendlines in the simultaneous bend as "ignore" .
*/ for (prop_list = bend->get_properties 0 ; prop_list ; prop_list = prop_list->next0 ) { prop - (BM_BEND_PROPERTY ♦) prop_list->get_obj () ; if (prop->is(BM_TYPE_BEND_SIMULTANEOUS) ) { bendlines = (DBM_ARRAY ) prop->get_bendlines() ; size = bendlines->get_size() ; for (i = 0 ; i < size ; i++) {
// get next bendline in the bend property object if (NULL == (bnd = (BM_BENDLINE ) bendlines->get (i) ) ) continue ; bl = parent->get_AD_bend_structure (bnd) ; if (NULL == bl) continue ;
// mark as ignore if (bl->adj_bodyl __ ! (bl->bodyl_drawn) __ bl != best_AD_bendline[0] ) { bl->bodyl_drawn = 1 ; b 1 - > d r a n_b n d_d i m_p o i n t 1 bodies_bend_f lange_list [0] ; b 1 - > dr awn_f 1 ange_dim_po in t 1 bodies bend flange list [2] ;
" " " } if (bl->adj_bodyl __ ! (bl->body2_drawn) &_ bl != best_AD_bendline [1] ) { bl->body2_drawn = 1 ; b 1 - > d r a n_b e n d_d i m_p o i n t 2 bodies_bend_f lange_list [1] ; bl - >drawn_f lange_dim_po int 2 bodies bend flange list [3] ;
/* mark this bendline for drawinσ
*/ if (best_AD_bendline[0] ) {
23 *
APPENDIX G best_AD_bendline [0] - >bodyl_drawn = 2 ; best_AD_bendline [0] - >drawn_bend_dim_point 1 bodies_bend_f lange_list [0] ; best_AD_bendline [0] - >drawn_f lange_dim_point 1 bodies bend flange list [2] ; i "f (be rst_AD_bendline [1] ) { best_AD_bendline [1] - >body2_drawn = 2 ; bes t_AD_bendl ine [1] - >drawn_bend_dim_point 2 = bodies_bend_f lange_list [1] ; best_AD_bendline [1] - >drawn_f lange_dim_point2 bodies " bend r flange list [3] ;
/*
Check if the flange-dim points is adjacent to a bendline. Here we will not check simultanoues bends, because they should have exactly the same flange-list as the one we have here now.
*/
BM_AD_dim_corner temp_point ; if (best_AD_bendline[0] ) { for (temp_point = bodies bend_f lange_list [4] ; temp_point ,- temp_point = temp_point->next) ~[ if (NULL == temp point->adj_bendline) continue ;
(best_AD_bendline [0] ->parent) ->compute_ef fects_f lange_length_draw n(best_AD_bendline [0] ->bend, best_AD_bendline [ 0 ] - >adj _bodyl , bodies_bend_f lange_list [0] , bodies_bend_f lange_list [2] , temp_point->adj_bendline) ;
if (best_AD_bendline[l] ) { for (temp_point = bodies bend_f lange_list [5] ; temp_point ; tempjpoint = temp_point->next) ~{ if (NULL == temp_point->adj_bendline) continue ;
(best_AD_bendline [1] ->parent) ->compute_ef f ects_f lange_length_draw n(best_AD_bendline [1] ->bend, best_AD_bendline [ l ] - >adj _body2 , bodies_bend_f lange_list [1] , bodies_bend_f lange_list [3] , temp point->adj bendline) ;
} ' "
}
24 APPENDIX G
/*
This function draws flange length for this bendline.
It uses the informat ion computed by compute_dim_points_to_display() f nction.
TODO : in this function we could keep track which bendline dimension points have already been drawn.
Sometimes bendline dimension points with respect to adj -bodyl and adj-body2 match. In that case we should draw it really only once. */ void BM AD_bendline: :draw_dimension_points 0
{
// qualification check if (! data_valid | | ignore) return ; if (adj_bodyl __ 2 == bodyl_drawn) { parent - >draw_dim_point ( dr awn_bend_dim_point 1 , drawn_f lange_dim_point 1 , parent - >view , parent->dc, parent - >obj ect_space_per_j?ixel ) ,- if (adj_body2 ScSc 2 == body2_drawn) { parent - >draw_dim_point ( dr awn_bend_dim_point 2 , drawn_f lange_dim_point 2 , parent - >view , parent->dc, parent - >ob j ect_space_per_pixel ) ;
}
/*
********** ********** ********** ********** **********
********** ********** ********** **********
BM_AUTO_DIMENSION class stuff.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
/*
This is a debug function.
*/ void BM AUTO DIMENSION: :test draw(void)
{ " "
BM_AD_dim_corner temp_point ; int i ; for (i = 0 ; i < num_of_bendlines ; i++) { if (! bends [i] ->data_valid) continue ;
25 APPENDIX G if (bends [i] ->adj_bodyl) {
(bends [i] ->bend_bodyl_point_left) .draw_with_dim_line (view,dc,obje ct_space_per_pixel) ;
(bends [i] ->bend_bodyl_point_right) .draw_with_dim_line (view, dc,obj ect_space_per_pixel) ; for (temp_point = bends [i] ->bodyl_points ; temp_point ; temp_ oint = temp_point->next) { temp_point->draw_with_dim_line (view,dc,object_space_per__pixel) ;
if (bends [i] ->adj_body2) {
(bends [i] ->bend_body2_point_left) .draw_with_dim_line (view,dc,obje ct_space_per_pixel) ;
(bends [i] ->bend_body2_point_right) .draw_with_dim_line (view,dc,obj ect_space_jper_pixel) ; for (temp_point = bends [i] ->body2_points ; temp_point ; temp__point = temp_point->next) { temp_point->draw_with_dim_line (view,dc,object_space_per_pixel) ;
}
/*
This function draws an info-box with bendline data for every bendline.
Idea : we will not check the bounding box of the visible portion of the part in the viewing area, because in SOLID mode renderware does not give out that kind of information.
Moreover, very often the user zooms in to see part dimensions, in which case there is no portion of the viewport that in not covered by the part, ie. the bounding box would cover the entire view area and would be practically useless.
Instead we will be drawing bendline information boxes along the edges of the viewing area.
We will divide the viewing area into 4 regions, and place bendline info boxes in those areas,
26 APPENDIX G whichever is closer to the bendline point to which the info-box refers to.
As of right now, we will be drawing those boxes along the left-right vertical edges of the viewport. */ void BM_AUTO_DIMENSION: :draw_bendline_data(CDC pdc)
{ int i, j ;
// these variables are used to calculate the info-box size and to draw it int font_height = 21 ; int font_avg_char_width = 8 ; // average width of a character int box_height = (font_height << 1) / 2 rows of text / ; int half_box_height = box_height >> 1 ; int box_width = font_avg_char_width 15 ; // space for 15 characters int box_x ; int vert_space_per_box ; int offset ;
// compute maximum number of info-boxes we can draw, int half_max_num_info_boxes = view_size_y / box_height ; if (half_max_num_info_boxes < 1) return ; // not enough screen space int max_num_info_boxes = half_max_num_info_boxes << 1 ;
/* compute the number of bends we can display
*/ int num_bends_to_be_drawn = 0 ; for (i = 0 ; i < num_of_bendlines ; i++) { if (! bends [i] ->data_valid | | NULL == bends [i] ->bend) continue ;
// remember, visibility of adj_bodyl bend-dimension points is always computed.
// here we only check visibility with respect to adj_bodyl.
// most likely visibility with respect to adj_bodyl and adj_body2 is the same. if ( (bends [i] ->bend_bodyl_point left) .visible | | (bends [i] ->bend_bodyl_point_right) .visible) (~ +}+num bends-to-be-drawn ; else continue ; if (num_bends_to_be_drawn >= max num_info_boxes) break ; // out of view space
27 APPENDIX G
// check if there are any bendlines to be drawn if (0 == num_bends_to_be_drawn) return ;
/* allocate space for storing bendline pointers and y-coordinates of endpoints.
*/
B M_AD_be n d l i n e ♦ ♦ be n d l i n e s = n e w
BM_AD_bendlineΛ [num_bends_to_be_drawn] ; if (NULL == bendlines) return ; // out of space double bend_y_coordinates = new double [num_bends_to_be_drawn] if (NULL == bend_y_coordinates) { // out of space delete [] bendlines ; return ; } BM_AD_dim_corner ♦ ♦bend_points = new
BM_AD_dim_cornerΛ [num_bends_to be_drawn] ; if (NULL == bend_points) delete [] bendlines ; delete [] bend__y_coordinates ; return ; }
/* collect bendline pointers and bend-dim-point pointers
*/ for (i = j = 0 ; i < num_of_bendlines ; i++) { if (! bends [i] ->data_valid | | NULL == bends [i] ->bend) continue ; if (! (bends [i] ->bend_bodyl_point_left) .visible ScSc ! (bends [i] ->bend_bodyl_point_right) .visible) continue ;
// first, decide which of the endpoints we will use bendlines [j] = bends [i] ; if ( (bends [i] ->bend_bodyl_point_left) .visible) { if (! (bends [i] ->bend_bodyl_point_right) .visible) bend_points [j] = _ (bends [i] ->bend_bodyl_point_left) ; else { i f
( (bends [i] ->bend_bodyl_point_left) . z_buf_value <
(bends [i] ->bend__bodyl_point_right) . z_buf_value) b e n d _ p o i n t s [ j ] _ (bends [i] ->bend_bodyl_point_lef t) ; e l s e b e n d _ p o i n t s [ j ]
Sc (bends [i] ->bend_bodyl_point_right) ;
elsebend_points [j] = -(bends [i] ->bend_bodyl_point_right)
if (++j >= num_bends_to_be_drawn) break ; // out of view space
28 APPENDIX G
}
/ * sort points according to which side of the screen the info-box should be right side contains all boxes (at least initially) whose bend-line-dim-point is not on the left side of the screen. */ int half screen = (view_size_x >> 1) ; i = 0 ; 7/ i will be top j = num_bends_to_be_drawn - 1 ; // j will be bottom
// we will use these to temporarily store stuff
BM_AD_bendline p aend ;
BM_AD_dim_corner p_bend_point ; while (i < j ) { while (i < j cSc bend_j?oints [i] - >screen_x < half_screen)
1 + + while ( i < j ScSc bend_points [ j ] - >screen_x >= half_screen) j - - ;
// switch i and j if d < j ) { p_bend = bendlines [i] ; p_bend_point = bend__points [i] ; bendlines [i] = bendlines [j ] ; bend_jpoints [i] = bend_points [j ] ; bendlines [j ] = p_bend ; bend_points [j ] = p_bend_point ;
if (bend_points [i] ->screen_x < half_screen) i++ ; // i points to the first info-box on the right side
/* check that neither side (ie. left-right) has too many info-boxes */ if (i > half_max_num_info_boxes) {
// too many boxes on the left side.
// sort them according to x-coordinates.
// this way we will move points with the largest x-coordiates to the right side. for (j = 0 ; j < i ; j++) bend_y_coordinates [j] = bend_points[j] ->screen_x ;
DBM_QuickSort_double(bend_y_coordinates, (unsigned long) i, (long ) bendlines) ;
29 APPENDIX G i} = half-max-num-info-boxes ; else if ( ( num_bends_to_be_drawn - i) > half max_num_info_boxes) {
// too many boxes on the right side.
// sort them according to x-coordinates.
// this way we will move points with the smallest x-coordiates to the left side. for (j = i ; j < num_bends_to_be_drawn ; j++) bend_y_coordinates [j] = bend_j?oints [j] ->screen_x ;
DBM_QuickSort_double (bend_y_coordinates + i, (unsigned long) (num_bends_to_be_drawn - i) ,
(long ) (bendlines + i) ) ; i} = num"bends to be drawn - half-max-num_info-boxes ;
// it could have been that when we chose a point for a bendline, it is not the best point.
// (although this point was used to place this point on the left-right side) .
// imagine a point on the left, it could be that both endpoints are visible, but
// out point is not the best, because the other endpoint of the bendline is actually to the // left of our point, for (j = 0 ; j < i ; j++) {
// check if we have choice if (! (bendlines [j] ->bend_bodyl_point_left) .visible | | ! (bendlines [j] ->bend_bodyl_point_right) .visible) continue ; if ( (bendlines [j] ->bend_bodyl_point_left) .screen_x < (bendlines [j] ->bend_bodyl_point_right) .screen_x) b e n d _ p o i n t s [ j ] Sc(bendlines [j] ->bend_bodyl_point_left) ; e l s e b e n d _ p o i n t s [ j ] =
-(bendlines [j] ->bend_bodyl_point_right) ; for (j = i ; j < num_bends_to_be_drawn ; j++) { // check if we have choice if (! (bendlines [j] ->bend_bodyl_point_left) .visible | | ! (bendlines [j] ->bend_bodyl_point_right) .visible) continue ; if ( (bendlines [j] ->bend_bodyl_point_left) . screen_x > (bendlines [j] ->bend_bodyl_point_right) .screen_x) b e n d _ p o i n t s [ j ] Sc (bendlines [ j] ->bend_bodyl_point_lef t) ; e l s e b e n d _ p o i n t s [ j ]
Sc (bendlines [j ] ->bend_bodyl_point_right) ;
30 H?Γ
APPENDIX G
// store the y-coordinate for Quicksort for (j = 0 ; j < num_bends_to_be_drawn ; j++) bend_y_coordinates [j] = bend_points [j] ->screen_y ;
// sort both sides according to the screen y-coordinate
// note a glitch : while the bendlines [] array has been permuted, the bend_points [] array has not been.
// in the next paragraph we restore the point array. TODO : may-be there is a better solution.
// we could resort the array, but then we need to get original y-coordinates array.
// we could just compute a separate permutation array, but then we need space for it, and
// the code to compute the permutation, which is non-tirivial .
// anyway, for now we just do it the easy way. if (i > 0) DBM_QuickSort_double (bend_y_coordinates, (unsigned long) i, (long ) bendlines) ; if ( ( num_bends _t o_be_d r awn - i ) > 0 ) DBM_QuickSort_double (bend_y_coordinates + i,
(unsigned long) (num_bends_to_be_drawn - i) , (long ) (bendlines + i) ) ; for (j = 0 ; j < i ; j++) { if ( (bendlines [j] ->bend_bodyl_point_lef t) .visible) { i f ( !
(bendlines [j] ->bend__bodyl_point_right) .visible) bend_points [j ] Sc (bendlines [j] ->bend bodyl_point_lef t) ; else i f
( (bendlines [j] - >bend_body l_po int lef t) .screen_x <
(bendlines [j] ->bend_bodyl_point_right) .screen_x) b e n d _ p o i n t s [ j ] Sc (bendlines [j] ->bend_bodyl_point_lef t) ; e l s e b e n d _ p o i n t s [ j ]
-(bendlines [j] ->bend bodyl point right) ;
. T e l s e b e n d _ p o i n t s [ j ]
Sc (bendlines [ j ] ->bend_bodyl_point_right ) ;
for (j = i ; j < num_bends_to_be_drawn ; j++) { if ( (bendlines [j] ->bend__bodyl_point_left) .visible) { i f ( !
(bendlines [j] ->bend_bodyl_point_right) .visible) bend_points [j] = -(bendlines [j] ->bend bodyl_point_left) ; else i f
( (bendlines [j] ->bend_bodyl_point_left) . screen_x >
31 APPENDIX G
(bendlines [j] ->bend_bodyl_point_right) .screen_x) b e n d _ p o i n t s [ j ] -(bendlines [j] ->bend_bodyl_point_lef t) ; e l s e b e n d _ p o i n t s [ j ]
_ (bendlines [j] ->bend bodyl_point_right) ;
} e l s e b e n d _ p o i n t s [ j ]
Sc (bendlines [ j ] ->bend_bodyl_point_right) ,-
/*
Ok, now we are ready for drawing. */ static char info_box_text [256] ; static POINT ■box_corners [5] ; static POINT arrow[3] ; BM_BENDLINE b ; BM_BEND_OP bop ; BM_2D_BODY ♦bjsody ;
/* draw left side */ int left = 3 ; int top ; if (0 == i) goto draw_right_side ;
// compute vertical space per info-box vert_space_per_box = view_size_y / i ;
// compute vertical offset for the top-left corner of the info-box offset = (vert_space_per_box - box_height) >> 1 ; box_corners [0] .x = box_corners [3] .x = box_corners [4] .x = left box_corners [1] .x = box_corners [2] .x = left + box_width ; for (j = 0 ; j < i ; j++) { b = bendlines [j] ->bend ; bop = b->get_bend_op () ; if (NULL == bop) continue ; // 043996KK if (view_type) b_body = b->get_current_3D_version0 ; else b_body = b->get_flat() ; top = j^vert_space_jper_box + offset ;
32 APPENDIX G box_corners [0] .y = box_corners [1] .y = box_corners [4] .y = top ; box_corners [2] .y = box_corners [3] .y = top + box_height ; sprintf (info_box_text, "A:%5.If,L:%6.2f" ,
(bop->get_bend_angle2 O ) 57.29578, (b_body->get_current_center_lin e 0 ) .get_len() ) ; pdc - >TextOut ( 5 , top , inf o_box_text , strlen(info_box_text) ) ; switch (bop->get_type 0 ) ( case BM_TYPE_BEND_OP_REGULAR : sprintf (info_box_text, "R:%5.2f,D:%5.2f",
( ( B M_ B E ND_O P _R E G U LAR ♦ ) bop) - >get_bend_radius ( ) , bop- >get_bend_deduction () ) ,- pdc- >TextOut (5 , top + font_height, inf o_box_text , strlen (info_box_text) ) ; break ; case BM_TYPE_BEND_OP_CONIC : // TODO : implement conic bend op. break ;
}
// draw box pdc->Polyline (box_corners, 5) ;
// draw arrow arrow [0] .x = left + box_width ; arrow [0] .y = top + half_box_height ;
// calculate arrow tip at fixed percentage length in from end point
C P o i n t ptLeft (bendlines [j] - >bend_body l_po in t _1 e ft . screen_x, bendlines [j] ->bend_bodyl__point_lef t . screen_y) ;
C P o i n t ptRight (bendlines [j] - >bend_body l_point_r ight . screen_x, bendlines [j] ->bend_bodyl_point_right . screen_y) ;
CSize sizeDiff = ptRight - ptLeft;
CPoint ptArrowTip; i f ( b e n d _ p o i n t s [ j ] = =
Sc (bendlines [j] ->bend_bodyl_point_lef t) ) ptArrowTip.x = ptLeft.x + sizeDiff .cx/8; ptArrowTip.y = ptLeft.y + sizeDiff.cy/8; else {
33 8*
APPENDIX G ptArrowTip. x = ptRight. x - sizeDif f . cx/8 ; ptArrowTip. y = ptRight. y - sizeDif f . cy/8 ; arrow [1] .x = ptArrowTip.x; arro [1] .y = ptArrowTip.y; pdc->Polyl ine (arrow, 2) ;
// change to solid pen for arrow heads
CPen* pArrowPen = new CPen ( PS_SOL I D
BCAD_context . m_nBendLineWeight , BCAD_context . m_crBend) ; CPen^ pOldPen = pdc->SelectObject (pArrowPen) ;
// compute arrow head CAutoDimArrow arrowBend( ptArrowTip,
CPoint(arrow[0] .x,arro [0] .y) ,
BCAD_context.m nArrowAngle,
BCAD_context.m_nArrowLength ) ;
// draw arrow head arrowBend.DrawHead(dc) ; pdc->SelectObject (pOldPen) ; delete pArrowPen;
}
/* draw right side
*/ draw_right_side : if (0 == num_bends_to_be_drawn - i) goto done ; box_x = view_size_x - box_width - 3 ; left = box_x ;
// compute vertical space per info-box vert_space_per_box = view_size_y / (num_bends_to_be_drawn - i)
;
// compute vertical offset for the top-left corner of the info-box offset = (vert_space_per_box - box_height) >> 1 ; box_corners [0] .x = box_corners [3] .x = box_corners [4] .x = left box corners [1] .x = box corners [2] .x = left + box width ;
34 APPENDIX G box_x += 2 ; for (j = i ; j < num_bends_to_be_drawn ; j++) { b = bendlines [j] ->bend ; bop = b->get_bend_op() ; if (NULL == bop) continue ; // 043996KK if (view_type) b_body = b->get_current_3D_version() ; else b_body = b->get_flat 0 ; top = (j - i) vert_space_per_box + offset ; box_corners [0] .y = box_corners [1] .y = box_corners [4] .y = top box_comers [2] .y = box_corners [3] .y = top + box_height ; sprintf (info_box_text, "A:%5.If,L:%6.2f" ,
(bop->get_bend_angle2 () ) ♦57.29578, (b_body->get_current_center_lin e() ) .get_len() ) ; pdc - >Text Ou t ( box_x , top, i n f o_box_ t ex t , strlen (info_box_text) ) ; switch (bop->get_type 0 ) { case BM_TYPE_BEND_OP_REGULAR : sprintf (info_box_text, "R:%5.2f,D:%5.2f" ,
( ( B M_ B EN D_O P_ R E G U L A R ) bop) ->get_bend_radius () ,bop->get_bend_deduction() ) ; pdc->TextOut (box_x, top + font_height, info_box_text, strlen(info_box_text) ) ; break ; case BM_TYPE_BEND_OP_CONIC : // TODO : implement conic bend op. break ; }
// draw box pdc->Polyline (box_corners, 5) ;
// draw arrow arro [0] .x = left ; arrow [0] .y = top + half_box_height ;
// calculate arrow tip at fixed percentage length in from end point
C P o i n t ptLeft (bendl ines [j] ->bend_bodyl_point_left . screen_x, bendlines [j] ->bend_bodyl_point_lef t . screen_y) ; ~
35 C«5t
APPENDIX G
C P o i n t ptRight (bendlines [j] - >bend_body l_poi t_r ight . screen_x , bendlines [j ] - >bend_bodyl_point_right . screen_y) ;
CSize sizeDif f = ptRight - ptLeft;
CPoint ptArrowTip; i f ( b e n d _ p o i n t s [ j ] = =
-(bendlines [j] ->bend_bodyl_point_left) )
{ ptArrowTip.x = ptLeft.x + sizeDiff.cx/8; ptArrowTip.y = ptLeft.y + sizeDiff.cy/8;
} else
{ ptArrowTip.x = ptRight.x - sizeDiff .cx/8; ptArrowTip.y = ptRight.y - sizeDiff .cy/8;
} arro [1] .x = ptArrowTip.x; arrow[1] .y = ptArrowTip.y; pdc->Polyline(arrow, 2) ;
// change to solid pen for arrow heads CPen* pArrowPen = new CPen ( PS_SOL ID
BCAD_context . m_nBendLineWeight , BCAD_context . m_crBend) ; CPen^ pOldPen = pdc->SelectObject (pArrowPen) ;
// compute arrow head CAutoDimArrow arrowBend ( pt rrowTip ,
CPoint (arrow [0] .x, arrow [0] .y) ,
BCAD_context . _nArrowAngle ,
BCAD_context . m_nArrowLength ) ;
// draw arrow head arrowBend . DrawHead ( dc ) ; pdc->SelectObject (pOldPen) ; delete pArrowPen;
}
/*
Done, release memory we allocated. */ done • delete [] bend_points ; delete [] bend_y_coordinates ; delete [] bendlines ;
36 APPENDIX G
/*
To draw part dimensions in the device context.
*/ int BM AUTO_DIMENSION: :draw_auto_dimensions (CDC target_dc)
{
BM_AD_dim_corner temp_pomt ; int i ;
// check that we have a valid dc if (NULL == target_dc) return 0 ;
// check if we need to recompute the data structures if (dirty) { if (! compute_auto_dimension_data () ) return 0 ,- if (dirty) return 0 ;
} if (NULL == part) return 1 ; dc = target_dc ;
// get view size view_size_x = view->get_viewport_width() ; view_size_y = view->get_viewport_height () ;
// create a mesh to determine clear spaces to draw dimensions Sc data pMesh = new CAutoDimRgnMesh(view_size_x, view_size_y) ;
// check if we need to compute points to ignore in solid i f ( v i e w - > g e t _d r a w i n g_m o d e ( ) Sc Sc ! points_to_ignore_in_solid_computed) { c}ompute points-to-ignore-in-solid0 ;
object_space_per_pixel = view->get_object_to_device_ratio 0 ;
// initially set all "ignore" flags to FALSE, we should not ignore anything.
// also, nothing is drawn yet. for (i = 0 ; i < num_of_bendlines ; i++) { bends [i] ->ignore = 0 ; bends [i] ->bodyl_drawn = bends [i] ->body2_drawn = 0 ;
/*
Compute visibility of all bendline dimension points of all bendlines .
37 APPENDIX G continue ; bends [i] ->draw_dimension_points ()
// test display of dirty region
CBrush brRed(RGB(255,0,0) ) ;
CBrush^ pOldBrush = dc->SelectObject (ScbrRed) dc->PaintRgn(pDirtyRegion) ; dc->SelectObject (pOldBrush) ; delete pDirtyRegion; pDirtyRegion = NULL;
/*
Create a pen for drawing the bendline info.
*/
// create the pen : type, (line)width, color.
CPen penBend;
CPen* pBendPen = create_auto_dim_pen ( _penBend ,
BCAD_context . m_nBendLineStyle , BCAD_context . m_nBendLineWeight ,
BCAD_context , m_crBend) ;
// select the new pen dc->SelectObject (pBendPen) ; dc->SetTextColor(BCAD context.m crBend) ;
/*
Draw bendline info. */ if (BCAD_context.m_bShowBendDim) draw_bendline_data (dc) ;
// Delete the mesh now that we are finished with it .
// delete pMesh;
/*
Restore old pen.
'/ dc->SelectObject (pOldPen) ; dc->SetTextColor(oldtextcolor) ; dc->SetBkMode (old_bk_mode) ;
// see if we have to disable auto-dimensioning in the view class if (reset_view_to_false_once_drawn) { reset_view_to_false_once_drawn = o ; view->set_auto_dimensions (0) ;
39 <fS4
APPENDIX G return 1
Figure imgf000496_0001
speed else {
CBrush brushNew(cr) ; LOGBRUSH lb; brushNew.GetLogBrush(Sclb) ;
DWORD dwStyleArray[6] ; int nStyleCount = 2 ;
DWORD dwDashLength = 2 + (nLineWeight 4) DWORD dwDotLength = dwDashLength / 4; DWORD dwGapLength = dwDashLength / 2 ; switch (nLineStyle)
{ case PS_DASH: dwStyleArray[0] = dwDashLength; // pixels on dwStyleArray[1] = dwGapLength; // pixels off nStyleCount = 2; break; case PS_DOT: dwStyleArray[0] = dwDotLength; // on dwStyleArray[1] = dwGapLength; // off nStyleCount = 2 ; break; case PS_DASHDOT: dwStyleArray[0] dwDashLength; // on dwStyleArray[1] dwGapLength; // off dwStyleArray[2] dwDotLength; // on dwStyleArray[3] dwGapLength; // off nStyleCount = 4 break; case PS_DASHDOTDOT: dwStyleArray[0] dwDashLength; // on dwStyleArray[1] dwGapLength; // off dwStyleArray[2] dwDotLength; // on dwStyleArray[3] dwGapLength; // off
40 APPENDIX G dwStyleArray[4] = dwDotLength; // on dwStyleArray[5] = dwGapLength; // off nStyleCount = 6; break; pPen->CreatePen(PS_GEOMETRIC | PS_USERSTYLE, nLineWeight, Sclb, nStyleCount, dwStyleArray) ;
} return pPen; }
void CBendCADDoc: :OnDrawAutoDim()
{
// if we have no dimension object, do nothing. if (NULL == auto_dim) { auto dim = new BM AUTO DIMENSION (this) ;
} " " " if (NULL == auto_dim) return ; '
CBendCADViewPart pActiveView = (CBendCADViewPart ) get_view (BENDCAD_VIEW_TYPE_PART) ; if (NULL == pActiveView) return ; if ( ! pActiveView- >get_auto_dimensions ( ) ) auto_dim->disable_view_dimensions_f lag_next_time 0 ; pActiveView- >set_auto_dimensions ( 1 ) ;
// always recompute dimension points aut o_dim- > inval idat e ( ) ; pActiveView- >Invalidate (0) ; }
41 APPENDIX H umuiutuuuuiuuu ii urn ///////////////////////////// / /// Example of auto dimensioning functions for computing u// // dimension points. Dimension points are computed // // before flange length dimensions are drawn. //
' //, Copyright 1996 AmadaSoft America, Inc. ////
// //
//////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BendCAD.h"
#include "BendCADDoc.h"
#include "BendCADViewPart .h"
#include "AUTODIM.HXX"
/*
********** ********** ********** ********** **********
********** ********** ********** ***.*******
BM_AD_bendline class stuff.
********** ********** ********** ********** **********
********** ********** ********** ********** */
/*
Thi s i s a l ocal f unc t ion used by
BM_AD_bendline : : comput e_BM_AD_f lange_points ( .. ) to compute the distance between a given reference point and an edge point .
It returns FALSE if the point is one the wrong side of the refrence line.
Vector dir should be a unit vector.
*/ static int compute_distance_from_ref__point (BM_P0INT const- pt / given reference point /,
BM_VECTOR const- dir / direction vector /,
BM_POINT +p /♦ point whose distance we want to compute /, double -distance)
{
BM VECTOR v(*p - pt) ; double x - v % dir ; if (x < -AUTODIM_DISTANCE_TOLERANCE) return 0 ; distance = x ; return 1 ;
}
/* APPENDIX H
A l o c a l f u n c t i o n u s e d b y
BM_AD_bendline : : comput e_BM_AD_f lange_points ( . . . ) .
Note : a dimension list we will be referring to is a list of flange dimension points.
A dimension list is open, it the number of dimension points in the list open to the "left" is not equal to the number of dimension point in the list open to the "right" .
Usually this means that the last flange dimension point we added to the list has no matching "closing" flange dimension point.
This whole thing is causes by the possibility that we can have a line (that looks like one line) actually broken into small pieces. In that case the user does not see those small pieces
(to him it looks like one line) and we don't want to consider points in the middle as legimate flange dimension points.
This function returns TRUE iff we can skip the given edge and leave the dimension list open, and FALSE iff we need to close the open dimension by creating a left-side dimension point from one of the end-points of the current edge.
Basically, this function returns TRUE iff the next edge in the loop is a line that will not be ignored, acutally, plus some more conditions.
Note : this function is called when the endpoint of the edge is at flange-length distance and we are considering whether we should draw a (flange) dimension point for this endpoint . */ static int leave_dimension_open(BM_EDGE ♦edge /♦ current edge ♦/, BM_LOOP bloop / loop where the current edge belongs to ♦/, BM_VECTOR const- side_vector / side vector for the current bendline-ajd_flange pair ♦/,
BM_VECTOR const- normal / normal of the plane underlying the adjacent flange ♦/)
BM_EDGE nex^edge = (BM_EDGE ) edge->next() ; if (NULL == next_edge) next_edge = bloop->get_first_edge () ; if (next_edge->is(BM_ENTITY_TYPE_LINE) ) {
// problem, if the next edge (which is a line) will be ignored, we need to APPENDIX H
// close the dimension here.
BM_VECTOR temp_v( ( ( (BM_LINE ) next_edge) ->get_v() ) side_vector) ;
// if the next line will not be ignored we can skip the current edge. if (temp_v.Len() > AUTODIM_DISTANCE_TOLERANCE _Sc (temp_v
% normal) < 0.0) {
// next edge is a line that will not be ignored.
// note that there is a problem, if this edge is a line, and one of the two lines
// (reme eber, next edge is a line) is adjacent to a bendline that
// the other is not adjacent to, we should close the dimension. if (! edge->is(BM_ENTITY_TYPE_LINE) ) return 1 ;
BM_3D_B0DY ^ab = edge->get_adj_body() ; BM_3D_BODY ab^ext = next_edge->get_adj_body() ; if (1 ab) { if ( ! ab_next) return 1 ; if (! ab_next->is(BMJ_NTITY_TYPE_BENDLINE) ) return 1 ; return 0 ;
} if (! ab_next) { if (! ab->is(BM_ENTITY TYPE_BENDLINE) ) return l ; return 0 ;
} if ((! ab->is(BM_ENTITY_TYPE_BENDLINE) ScSc ! ab_next->is(BM_ENTITY_TYPE_BENDLINE) ) | | ab == ab_next) return 1 ;
» '
// if next edge is not a line, we have to close the open dimension return 0 ;
}
/*
A l o c a l f u n c t i o n u s e d b y
BM_AD_bendlin : : comput e_BM_AD_flange_points (...) .
This function creates a dimension point in the most general
3 APPENDIX H form.
We assume that we are creating the dimension point for a line. This line could be adjacent to a bendline.
*/ static BM_AD_dim_corner ♦create_dim_point (double d / bendline arc outside length projected onto our plane /,
// these are basic parameters needed to draw any dimension point BM_POINT const- p /♦ point p in the flange dimension point /, BM VECTOR const- rv / reference vector to make sure point p in the flange dimension point is on the same plane as defined by the bendline dimension point
*/' BM_VECT0R const- opening_directιon_vector / for flange dimension point /, int opening_vector_reverse_bit,
BM_AD_bendline owner,
BM_3D_BODY ♦Body_required_visible,
BM_AD_dim_corner ♦♦prev /♦ previous flange dimension point in the list of flange dim points /,
BM_VECT0R const- side_vector, // these parameters are used when the line for which we are computing the dimension point is adjacent // to another bendline. double d_proj_side_vector / d projected onto the side-vector : angle_factor^d in compute_BM_AD_flange_points ( ... ) /,
BM_VECTOR Sc bend_arc_direction /♦ direction of the bend arc projected onto our plane /
/ should be line->v plane normal /,
BM_VECTOR _ bend_direction /* points to the direction in which the bendline "turns" ♦/
/ depends on whether the bend angle is acute or not. ♦/ / if acute then tangent to the other end of bend arc ♦/ / if not acute, then an endpoint of the tangent approximation /
/ basically this is the (p->p2) vector for the other bendline with respect to this flange ♦/,
BM_BENDLINE *adj_bendline / if the line is adjacent to a bendline this is a pointer to it ♦/
/ this parameter is stored to avoid drawing some di enions twice ♦/,
BM_LINE const- adj_bend_p2_line / this is the line between p2 points of the bend-dimension ♦/
/ points of the adjacent bendline with respect to this flange /
/ note that our p2 point has to be on that line. ♦/ /* usually our p->p2 vector is perpendicular to this line, although not always ♦/ ) CΓΌ
APPENDIX H
// this our local copy of the adj-bendline-pointer BM_3D_BODY ♦adj^end = adj_bendline ;
BM_POINT p_local (p + rv) ;
// note : even if this line is adjacent to another bendline,
// but if the line we are creating the flange dimension point for is not perpendicular to
// the side-vector, we should not memorize that this flange dimension point is adjacent to
// a bendline, because the flange length dimension drawn at this flange dimension point
// is not parallel to the side-vector of the adjacent bendline with respect to this flange. if (adj_bendline _SL fabs (bend_arc_direction % side_vector) < (bend_arc_direction.Len0 - AUTODIM_DISTANCE_TOLERANCE) ) { // not perpendicular adj bendline = NULL ;
} "
// check if the line is attached to a bendline if (d <= AUTODIM_DISTANCE_TOLERANCE) (
// not attached to a bendline, or both thickness and bendline radius are 0.
// create a 1-point flange-dimension point. // note that body_required_visible points to the flange with respect to which
// the dimension point is computed. return new BM_AD_dim_corner (p local, owner, Body_required_ isible, o p e n i n g _ d i r e c t i o n _ v e c t o r , opening_vector_reverse_bit , prev, adj_bendline) ;
// note that since we have 3 points now, this line is adjacent to another bendline.
// compute pi. p_local is pi.
// compute p
BM_POINT dim_p (p_local + d_proj_side_vector^side_vector) ;
// compute p2 bend_arc_direction.set_length(d) ;
BM_POINT dim_p2 (p_local + bend_arc_direction) ;
// now the problem is that with respect to the adjacent bendline, our flange dimension points
// p and pi might not be on the outside - they could be on the inside. SOI
APPENDIX H
// the distance from p to p2 depends on that.
// however, we know the p2-line of the adjacent bendline (with respect to our flange) ,
// so we will compute the distance between that p2-line and dim_p2.
// we will use that to compute the correct p2 point for our flange dimension (note that
// our p2 point has to be on the p2-line of the adjacent bendline) . double distance ;
BM_distance_between_point_and_line (dim_p2, adj_bend_p2_line, -distance, (BM_P0INT ) NULL) ; bend_direction.set_length(distance) ; dim_p2 = dim_p2 + bend_direction ;
// note that the body_required_visible pointer points not to this flange, but to the
// adjacent-bendline instead, ALWAYS, even if this flange dim point will not be marked as
// adjacent to another bendline. return new BM_AD_dim_corner(dim_p, p_local, dim_j?2, owner, adj_bend ? adj_bend : Body_required_visible, opening_direction_vector, opening_vector_reverse_bit, prev, adj bendline) ;
}
/*
This function computes flange dimensions points with respect to an adjacent flange.
Note : The reference point computed right in the beginning of the function is given in order to make sure we can handle any kind of adj-body surface.
The first problem is that we don't know whether the 2D-body of the 3D-version of the adj-body represents the OUTSIDE or INSIDE. We do know that the bendline dimension points for the bendline are OUTSIDE points. However, it could be that the adj -body represents the INSIDE explicitly.
In that case we use to reference point (which is on the outside surface of the adj-body) to compute a translation vector by which we will shift all point we are going to compute here.
Also we will use this translation vector to make sure the points pi and p2 of the flange dimension point are correct .
(if the adj-body represents inside, we compute dimension points really for outside and the line
(p->p2) has to be constructed with care - it is shorter than APPENDIX H line (p->pl) ) .
Note : this function is very much like BMAPI's BM_2D_B0DY: :compute_outside_width( ... ) function, although we make more assumtions here.
*/
Figure imgf000504_0001
// flange dimension points we are go ng to compute will be stored here
BM_AD_dim_corner ♦♦list_of_points ; // list_of_points is where we write the pointer to the
// next flange dimension point
BM_AD_dim_corner temp_dp ;
// these parameters are used as input to this function. double flange_length ; / it is important that the flange length be the correct flange length./
BM_POINT ref_point ,- / reference point, defines the right plane for flange dimension points /
BM_VECTOR side_vector ; / should be normalized /
// check which adjacent body we compute if (adj_body == adj_bodyl) { flange_length = fll ; list_of_points = _bodyl_points ; ref_point = bend_bodyl_point_left .p ; side vector = side vectorl ;
} " " else if (adj_body == adj_body2) { flange_length = fl2 ; list_of_points = _body2_points ; ref_point = bend_body2_point_left.p ; side vector = side vector2 ;
} " else return 0 ; // not an adjcent body
// variables to store temporary values BM_VECTOR temp_v ; double temp_x ;
// parameters for fixing the reference point
BM_POINT rp (ref_point) ; // this a local copy of the reference point, we will modify it.
BM_VECTOR rv ; // a vector for translating flange dimension points. int ref_vector_valid = 0 ; // if this is TRUE, we need to translate all flange dimension points. 50i
APPENDIX H
// if TRUE, the only really tricky part is to construct the p2 point in the flange dimension point.
// qualification check BM_2D_BODY ♦adj_displayed_version ; if (parent->get_view_type () ) adj_displayed_version adj_body->get_current_3D_version() ; else adj_displayed_version = adj_body->get_flat 0 ; if (NULL == adj_displayed_version) return 0 ;
BM_SURFACE ♦surface = adj_displayed_version->get_surface 0 ; if (NULL == surface) return 0 ;
BM_LOOP ♦bloop = adj_displayed_version->get_bloop 0 ; if (NULL == bloop) return 0 ;
BM_EDGE Aedge ; // here we will store edges as we scan the loop. double distancel, distance2 ; // here we will store the distance of points we see double dl, d2 ; // here we store distance that has to be added because of a bend arc. for lines adjacent to a bendline. double tdl, td2 ; // here we store the total distance which is the sum of distanceX + dX.
BM_3D_B0DY *ab ; // here we store a pointer to a body that is adjacent to the current edge.
BM_BEND_0P ^bop ; // here we store a pointer to the bend op associated with the bendline that is
// adjacent to the edge we scan (valid only iff the body adjacent to the edge is a bendline) .
BM_VECTOR right_opening_direction ; // this is the right-side opening direction vector.
BM_VECTOR left_opening_direction ; // this is the left-side opening direction vector. int fl_dim_open = 0 ; // if this is TRUE, we have created a right-side flange dimension point, but
// no corresponding left-side dimension point. That is, the dimension is "open" .
BM_VECT0R bend_arc_direction ; // direction of the bend arc projected onto our plane
// should be line->v plane_normal. Used when a line is adjacent to a bendline.
BM_VECTOR bend_direction ; // points in the direction in which the bendline "turns"
// depends on whether the bend angle is acute or not. // if acute then tangent to the other end of bend arc. // if not acute, then an endpoint of the tangent approximation.
// basically this is the (p->p2) vector for the other bendline with respect to this flange.
// this is used when a line is adjacent to a bendline, to compute the p2 point for
8 SOW
APPENDIX H
// the flange dimension point. BM_LINE adj_bend_p2_line ; // this is the left-right-p2 line, of the adjacent bendline,
// with respect to this flange.
// this is used when a line is adjacent to a bendline, to compute the p2 point for
// the flange dimension point, double bend_arc_outside_length_proj ; // bendline arc outside length projected onto our plane
/*
Handle surface types.
*/ if (surface->is (BM_TYPE_PLANE) ) goto handle_planes ;
/*
********** ********** ********** ********** ********** **********
********** ********** ********** temporary resctiction : we only handle surfaces that are planes.
TODO : handle other surface types.
********** ********** ********** ********** ********** **********
********** ********** **********
*/
// unknown surface return 0 ;
/*
Here we handle planes
*/ handle_ lanes :
BM_PLANE plane = (BM_PLANE ) surface ;
// we assume that the reference point correctly defines the plane (which is parallel to our plane)
// that is the OUTSIDE plane.
// check if reference point is on our plane. If not (in that case our plane represents the INSIDE
// plane) compute a translation vector for moving from our plane to reference plane,
// and move the reference point to our plane. rv = plane->get_normal 0 ; rv.normalise 0 ; temp_v = rp - (plane->get_pt () ) ; temp_x = temp_v % rv ; if (fabs (temp_x) > AUTODIM_DISTANCE_TOLERANCE) {
// ok, need to translate all dimension points, reference point not on the plane. ref vector valid = 1 ; APPENDIX H rv. set_length(temp_x) ; rp = rp + (-rv) ;
} else rv = BM_null_vector ;
// compute right- and left-side opening vectors. right_opening_direction = side_vector (plane->get_normal C right_opening_direction.normalise () ; left_opening_direction = - (right_opening_direction) ;
/ *
********** ********** ********** ********** **********
********** ********** ********** **********
Main portion of this function. Scan the bounding loop of the adj_body and construct dimension points.
Notice that we only need to scan the bloop since the edge that is the farthest away from the given line has to be in the bloop. ********** ********** ********** ********** **********
********** ********** ********** **********
Note : when the dimension list is open, the last right-side dimension point created must be different from the start-point of the current edge, at the beginning of the loop.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
// scan all edges in the bloop
// first, we have a problem where to start scanning.
// if we start from the first edge, we basically start from an arbitrary edge.
// this might not be good since we might create dimension points we don't really want.
// therefore we will find an edge that is adjacent to our bendline and start from that and
// finish when we get back to it.
BM_EDGE star^edge, stop_edge, +next_edge ; for (start_edge = bloop->get_first_edge () ,- start edge ; start_edge = (BM_EDGE ) start_edge->next () ) { ~" if (start_edge->get_adj_body() == bend) break ; // edge adjacent to this bendline is a good start-edge else if (! start_edge->is (BM_ENTITY_TYPE_LINE) ) break ; // any non-line is a good start-edge else { // any line that will be ignored is also a good place to start temp_v = ( ( (BM_LINE *) start_edge) ->get v()) ♦ side_vector ; ~
10 APPENDIX H
// in these two cases this line will be ignored if (temp_v.Len() <= AUTODIM_DISTANCE_TOLERANCE) break ; // line parallel to the side-vector if ( (temp_v % plane->get_normal () ) > 0.0) break ; // material "above" the line
if (NULL == start_edge) {
♦list_of_points = NULL ; return 1 ;
}
// this is the main loop.
// initially we set stop_edge to NULL, we would like to set it to start-edge, but we cannot,
// because in that case we would never enter the loop, therefore we set it to NULL and right
// after we enter the loop, we set it to start_edge.
// (this is important in the case when the loop consists of only one circle) . stop_edge = NULL ; for (edge = start_edge ; edge != stop_edge ; edge = next_edge)
{ stop_edge = start_edge ;
// compute the next edge we will scan next_edge = (BM_EDGE ) edge->next() ; if (NULL == next_edge) next_edge bloop->get_first_edge () ; switch (edge->get_type 0 ) { case BM_ENTITY_TYPE_LINE : { // compute distance for start- and end-points
// first, we want to ignore lines that are parallel to the side-vector.
// we also want to ignore lines that have material "above" them when looking in the
// side-vector direction (because they cannot have to largest width, since material is
// "above" them, there must be some other edge bounding the body from above) . temp_v = ( ( (BM_LINE ♦) edge) ->get_v() ) ♦ side_vector ; if (temp_v.Len() <= AUTODIM_DISTANCE_TOLERANCE) continue ; // line parallel to the side-vector if ( (temp_v % plane->get normal () ) > 0.0) continue ; // material "above" the line
// note that this leaves only lines whose direction-vector goes to the "left"
11 APPENDIX H // of the side-vector.
// we need to check if this line is adjacent to a bendline ab = edge->get_adj_body() ;
// check if this line is adjacent to a valid bendline (ie. one that is not the
// bendline associated with this BM_AD_bendline obj ect ) . dl = d2 = bend_arc_outside_length__proj = 0 . 0 ; i f ( a b Sc Sc a b ! = b e n d Sc Sc ab- >is (BM_ENTITY_TYPE_BENDLINE ) ) {
// check if the bendline is being bent bop = ( (BM_BENDLINE ) ab) - >get_bend_op 0
; if ( (parent->get_view_type () ) / have to have a 3D view * I ScSc
( ( B M _ B E N D L I N E ) ab) ->get_bending_status 0 ScSc bop) {
// a problem : it could be that the bendline is not perpendicular to the side-vector.
// in that case we need to project the bend-arc-approximation-value onto the side-vector.
// for example, if the bendline is parallel to the side-vector, we should not add
// the approximation value at all, since it plays no role in the width computation. temp_x = side_vector Λ ( ( (BM_LINE ♦) edge) ->get_v() ) ; // temp_x is "angle_factor" if (temp_x > PI_over_2) temp_x = PI - temp_x ; temp_x = sin(temp_x) ; switch (bop->get_type 0 ) { case BM_TYPE_BEND_OP_REGULAR : bend_arc_outside_length_proj = ( (BM_BEND_OP_REGULAR ♦) bop) ->compute_3D_outside_approx_per_side () ; d 1 temp_x^bend_arc_outside_length_proj ; d2 = dl ; // d2 is the same as dl ! break ; // TODO : implement more bend operations here. default : ; // unknown bend op }
// compute some needed parameters // compute : direction of the bend arc projected onto our plane
12 APPENDIX H *)
dy,
Figure imgf000510_0001
int to anything we don't want to.
// handle two cases separately - depending on whether the dimension list is open or not. if (fl_dim_open) {
// if the dimension is open, we don't need to check the start-point of the line,
// since it is at the flange length distance anyway.
//
// first we will check if the line is perpendicular to the side-vector if (fabs (side_vector % ( (BM_LINE ) edge) ->get_v() ) > AUTODIM_DISTANCE_TOLERANCE) {
// not perpendicular. // this line has to be "coming down" (because it is not perpendicular to the
Figure imgf000510_0002
close the dimension here by creating
// a left-hand-side dimension point
13 APPENDIX H from the end-point of the line .
// if the next edge is a line , we can iust continue . i f
(leave_dimension_open (edge , bloop , side_vector , plane - >get_normal 0 ) ) break ;
) , s , ♦ )
Figure imgf000511_0001
// this is a small trick that will save us some time.
// if the next edge is a line that will be ignored, we can skip is right now here. i f
(next_edge->is (BM_ENTITY_TYPE_LINE) ScSc next_edge != stop_edge) { next_edge = (BM_EDGE ) edge->next() ; if (NULL == next_edge) next_edge = bloop- >get first edge ( ) ;
break ;
} if (! compute_distance_from_ref_j>oint (rp, side_vector, edge->get_edge_startpoint () , distaneel)) continue ,- if (! compute_distance_from_ref_point (rp, side_vector, edge->get_edge_endpoint () , distance2) ) continue ; tdl = distaneel + dl ; td2 = distance2 + d2 ;
// check if the start-point is a flange dimension point if (fabs (tdl - flange length) <= AUTODIM_DISTANCE_TOLERANCE) {
// check if the second point is a flange dimension point
14 3
APPENDIX H if (fabs(td2 - flange_length) > AUTODIM_DISTANCE_TOLERANCE) {
// only start-point is a flange dimension point.
// create a left-right (ie. in both directions) flange dim point and continue. i f ( t e m p _ d p create_dim_point (bend_arc_outside_length_proj ,
( ( B M _ L I N E ) edge) ->get_startpt () , rv, right_opening_direction, 1, this, adj_body, list_of_points, side_vector, dl, bend_arc_direction, bend_direction, (BM_BENDLINE ) ab, adj_bend_p2_line) ) { l i s t _ o f _ p o i n t s Sc (temp dp->next) ;
} break ;
}
// else open the dimension list // create right flange dimension point from start-point i f ( t e m p _ d p create_dim_point (bend_arc_outside_length_proj ,
( (BM_LINE *) edge) ->get_startpt () , rv, right_opening_direction, 0, this, adj_body, list_of_points, side_vector, dl, bend_arc_direction, bend_direction, (BM_BENDLINE ) ab, adj_bend__p2_line) ) { list_of_points = _(temp_dp->next) ;
// check if we can leave the dimension list open and continue i f
(leave_dimension_open(edge,bloop,side_vector,plane->get_normal () ) ) fl_dim_open = 1 ; break ;
} // create left flange dim point from end-point . i f ( t e m p _ d p create_dim_point (bend_arc_outside_length_proj ,
((BM_LINE ^) edge) ->get_endpt 0 , rv, left_opening_direction, 0, this, adj_body, list_of_points, side_vector, dl, bend_arc_direction, bend_direction, (BM_BENDLINE ♦) ab,
15 APPENDIX H adj_bend_p2_line) ) { list_of_points = _(temp_dp->next) ;
// ok, close the dimension list. fl_dim_open - 0 ;
// this is a small trick that will save us some time.
// if the next edge is a line that will be ignored, we can skip is right now here. if (next_edge->is(BM_ENTITY_TYPE_LINE) __ next_edge != stop_edge) { next_edge = (BM_EDGE ) edge->next()
/" if (NULL == next_edge) next_edge = bloop->get_first_edge 0 ; break ;
} else if (fabs(td2 - flange_length) >
AUTODIM_DISTANCE_TOLERANCE) {
// the start-point is not a flange dimension point
// if the end-point is also not a flange dimension point, we can continue. continue ;
}
// ok, only the end-point is a flange dimension point.
// two possibilities, if we can leave the dimension list open (right now dimension is
// closed!) we don't even have to open it, we can just continue. i f
(leave_dimension_open(edge,bloop, side_vector,plane->get normal () ) ) break ;
// second possibility, now we have to create a left-right flange dimension point.
// dimension list stays closed. i f ( t e m p _ d p create_dim__point (bend_arc_outside_length__proj ,
( (BM_LINE ) edge) ->get_endpt 0 , rv, right_opening_direction, 1, this, adj__body, list__of_points, side_vector, dl, bend_arc_direction, bend_direction, (BM_BENDLINE ♦) ab, adj_bend_p2_line) ) { list_of_points = _(temp_dp->next) ;
16 APPENDIX H
// this is a small trick that will save us some time.
// if the next edge is a line that will be ignored, we can skip is right now here. if (next_edge->is(BM_ENTITY_TYPE_LINE) _Sc next_edge != stop_edge) { next_edge = (BM_EDGE ) edge->next() ; if (NULL == next_edge) next_edge bloop->get_first_edge 0 ;
break ; case BM_ENTITY_TYPE_ARC : {
// note : we can always ignore the start-point of the arc !
// because of the way we keep track of the open dimension list
// make sure the -dimension list will be closed. fl_dim_open = 0 ;
// first, compute start- and end-angles of the arc with respect to the side vector.
// ie. convert start- and end-angles so as if the side-vector was the 0-angle vector. double startang = ( (BM_ARC ) edge) ->get_startang() ; double endang = ( (BM_ARC ) edge) ->get_endang()
; temp_v = side_vector* ( ( (BM_ARC ) edge) ->get_vx() ) ; double delta_angle = (temp_v.Len() ) / ( ( (BM_ARC ♦) edge) ->get_rad() ) ; if (delta_angle < -1.0) delta_angle = -1.0 ; else if (delta_angle > 1.0) delta_angle = 1.0 delta_angle = asin(delta_angle) ; i f ( f a b s ( ( ( ( B M _ A R C ) edge) ->get_normal O ) %temp_v) > 0.0) { startang += delta_angle ; endang += delta_angle ; if (startang > PI_times_2) startang -= PI_times_2 ; if (endang > PI_times_2) endang PI_times_2 ; else { startang -= delta_angle ; endang -= delta_angle ;
17 APPENDIX H if (startang < 0.0) startang += PI_times_2
; if (endang < 0.0) endang += PI times 2 ;
}
// compute the extreme point
BM_POINT arc_extreme_point ;
// 0-angle point is the extreme point if (endang < startang) arc_extreme_point = ( (BM_ARC ♦) edge) ->get_center () + ( ( (BM_ARC ♦) edge) ->get_rad() ) side_vector ; else arc_extreme_point = ( ( (BM_ARC ♦) edge) ->get_edge_endpoint () ) ;
// check the distance of the extreme point if (! compute_distance_from_ref_point (rp, side_vector, Scarc_extreme_point, distaneel)) continue ; if (fabs (distaneel - flange_length) <= AUTODIM_DISTANCE_TOLERANCE) {
// if we have the 0-angle point, create a left-right flange dimension point.
// otherwise if next line is a non-ignored line, don't do anything,
// otherwise create a left-right flange dimension point. if (endang >= startang _SL leave dimension open(edge,bloop,side vector,plane->get normal 0 ) )
{ continue ;
}
// create a left-right flange dimension point , dimension list stays closed .
// this is a 1 -point flange dimension point . if (temp_dp = new BM_AD_dim_corner (rv + arc_extreme_point , this , adj_body, r ight_opening_di rect ion , 1 , list_of_points , NULL) ) ( list_of_points = Sc (temp_dp- >next) ;
) ' ' break ; case BM_ENTITY_TYPE_CIRCLE :
// circles are a much simpler version of the arc case.
{
BM_P0INT circle_extreme_point = ( (BM CIRCLE ♦)
18 APPENDIX H edge) ->get_center 0 + ( ( (BM_CIRCLE ) edge) ->get_rad() ) side_vector
// we won't check the distance since it must be a flange dimension point
// create a left-right flange dimension point. // this is a 1-point flange dimension point, if (temp_dp = new BM_AD_dim_corner (rv + circle_extreme_point, this, adj__body, right_opening_direction , 1 , list_of_points, NULL)) { list of points = _(temp dp->next) ;
> ' " " break ; case BM_ENTITY_TYPE_ELLIPSE : // TODO : implement ellipse here, should be similar to the way arc is handled, continue ; break ; default : continue ; // unknown edge type
}
}
/*
Ok, all done.
*/
♦list_of_points = NULL ; return 1 ; }
/*
This function computes bendline dimension points for one
BM_AD_bendline structure.
Note : pi is on the plane of adjacent body for which the flange length is drawn. p is the centerpoint . p2 is the point on the side of the bendline.
Note : in this function we always compute bend-dimension points with respect to adj -bodyl and adj-body2. In might that we need to know the visibility of
19 APPENDIX H these points in the future, although this bendline might have 1 or 0 adjacent bodies.
*/ int BM_AD_bendline: :compute_BM_AD_bendline (void) double metal_thickness ; // thickness of the sheetmetal BM_2D_BODY ♦bendline_displayed_version ; // 3D-version of the bendline
BM_VECT0R temp_v ; // vector used for very short periods for storing temporary stuff
// initally mark the bendline data as invalid, in case we fail here. data_valid = 0 ;
// qualification check if (NULL == bend) return 0 ; if (NULL == bend->get_adj_list 0 ) return 0 ; if (NULL == bend->get_part () ) return 0 ,-
// this bendline has to have a 3D-version if (parent->get_view_type () ) { if (NULL == (bendline_displayed__version bend->get_current_3D_version0 ) ) return 0 ;
(bendline_displayed_version
Figure imgf000517_0001
metal_thickness = (bend->get_part 0 ) ->get_metal_thickness () ;
/* ********** ********** ********** ********** ********** ********** ********** ********** ********** this is a temporary measure, we only process regular bendlines. ie. ignore conic bendlines. 03/16/96. KK. / if (bend->get_bending_status 0 __ bend->get_bend_op 0 _Sc
! (bend->get_bend_op() ) ->is (BM_TYPE_BEND_OP_REGULAR) ) return 0 ; /* ********** ********** ********** ********** ********** ********** ********** ********** ********** *
// get the number of adjacent bodies. adj_bodyl = (bend->get_adj_list () ) ->f ind_lowest_id_adj_body () a d j _ b o d y 2 (bend->get_adj_list () ) ->f ind_second_lowest_id_adj_body () ; num_of _adj acent bodies = (adj bodyl ? 1 : 0) + (adj bodv2 ? 1 : 0) ; " -
/*
20 APPENDIX H Compute side vectors.
* / if (adj_bodyl) ( i f ( ! bendline_displayed_version->compute_vector_perp_towards_adj_body( adj_bodyl, side_vectorl) ) return 0 ; side_vectorl.normalise() ; if (adj_body2) { i f ( ! bendline_displayed_version->compute_vector_perp_towards_adj_body( adj_body2, side_vector2) ) return 0 ; side vector2.normalise() ;
} "
/*
Compute bendline dimension points.
*/ if (! bend->get_bending_status () / bendline not bent ♦/ | |
! parent->get_view_type 0 / flat view /) {
// note : here we don't know whether the dimension point is OUTSIDE or INSIDE.
// this has to be taken into account later.
// however, it should work either way. bend_bodyl_point_lef t . num_of_points bend_bodyl_point_right .num_of_points = 1 ; bend_bodyl_point_lef t . can_reverse_opening_dir bend_bodyl_point_right .can_reverse_opening_dir = 0 ; b e n d _ b o d y l _ p o i n t _ l e f t . p (bendline_displayed_version->get_current_center_line 0 ) ,get_start pt 0 ; b e n d _ b o d y l _ p o i n t _ r i g h t . p =
(bendline_displayed_version->get_current_center_line () ) .get_endpt ()
// note opening directions, left will get start-point, right will get end-point, ie. vector goes left->right. bend_bodyl_point_right . opening_direction (bendline_displayed_version->get_current_center_line () ) .get_v() ;
(bend_bodyl_point_right . opening_direction) . normalise ( ) ; bend_bodyl_point_left . opening_direction - (bend_bodyl_point_right .opening_direction) ;
// points with respect to both adjacent bodies are the same bend_body2_point_lef t . num_of_points bend_body2_point_right .num_of_points = 1 ;
21 APPENDIX H bend_body2_point_lef t . can_reverse_opening_dir bend_body2_point_right . can_reverse_opening_dir = 0 ,- bend_body2_point_right . opening_direction bend_bodyl_point_right . opening_direction ; bend_body2_point left . opening_direction bend_bodyl_point_lef t .opening_direction ; bend_body2_point_left .p = bend_bodyl_point_lef t .p ; bend_body2_point_right .p = bend_bodyl_point_right .p ; else (
// first, get some bending parameters B M _ S U R F A C E s u r f a c e bendline_displayed_version->get_surface () ; if (NULL == surface) return 0 ; BM_BEND_OP bop = bend->get_bend_op0 ; if (NULL == bop) return 0 ; double bend_angle = bop->get_bend_angle20 ; double bend_arc_angle = PI - bend_angle ; double half_bend_arc_angle = bend_arc_angle/2.0 ; switch (surface->get_type () ) I case BM_TYPE_CYLINDER : { // note that the bend op can be both regular and conic
BM_CYLINDER cylinder = (BM_CYLINDER ) surface
; double radius = cylinder->get_rad() ; double outside_radius = radius ; if (bendline_displayed_version->get_sense () ) outside_radius += metal_thickness ;
// set some common values bend_bodyl_j?oint_left .can_reverse_opening_dir = bend_bodyl_point_right.can_reverse_opening_dir = 0 ; bend_bodyl_point_right .opening_direction (bendline_displayed_version->get_current_center_line () ) .get_v() ;
(bend_bodyl_point_right.opening_direction) .normalise () ; bend_bodyl_point_left .opening_direction - (bend_bodyl_point_right.opening_direction) ; i f ( o u t s i d e _ r a d i u s < =
AUTODIM_DISTANCE_TOLERANCE) {
// special case : outside radius 0 - trivial dimension point. bend_bodyl_point_lef t . num_of _points bend_bodyl_point_right .num_of_points = 1 ; bend_bodyl_poi nt_l e f t . p (bendline_displayed version- >get current center line()) .qet start pt() ; ~ - b e n d_b o dy 1 _p o i n t __ r i g h t . p
22 51 Ϋ
APPENDIX H
(bendline_displayed_version->get_current_center_line ) .get_endpt () ; bend_body2_point_lef t .num_of_points bend_body2_point_right .num_of_points = 1 ,- bend_body2_point lef t . can_reverse_opening_dir bend_body2_point_right . can_reverse_opening_dir = 0 ; bend_body2_point_right . opening_direction = bend_bodyl_point_right .opening_direction ; bend_body2_point_lef t . opening_direction= bend_bodyl_point_lef t .opening_direction ; bend_body2_point_le f t . p bend_bodyl_point_lef t . p ; bend_body2_point_right . p = bend_bodyl_point_right . p ; else { bend_bodyl_point_lef t . num_of _points bend_bodyl_ρoint_right .num_of_points = 3 ;
// compute points pi for adj_bodyl bend_bodyl_point_lef t . pl
(bendline_displayed_version->get_current_center_line () ) .get_start pt 0 ; bend_bodyl_point_right . pl
( bendl ine_displayed_version->get_current_center_lme ( ) ) .get_endpt ( )
;
// the problem now is that it could be that these centerline points (which are
// on the surface of the bendline) , could be only inside surface of the bendline. i f
(bendline_displayed_version->get_sense 0 ScSc metal_thickness > AUTODIM_DISTANCE_TOLERANCE) { temp_v = cylinder->get_vx0 ,- temp_v.set_length(metal_thickness) ; bend_bodyl_point_left .pl bend_bodyl_point_left.pl + temp_v ; bend_bodyl_point_right.pl bend bodyl -point right.pl + temp v ;
} "
// a break in the computation of adj_bodyl.pi .
// store current pi values for adj_body2 as well, this will save some time.
//
// note that we should not really compute adj_body2 points unless adj_body2 pointer
23 APPENDIX H
// is not NULL. However, this point (adj_body2.pl) is very useful for computing
// adj_bodyl.p2 (if angle is acute) . so we compute it anyway. bend_body2_point_lef t . pl bend_bodyl_point_left.pl ; bend_body2_point_right . pl bend_bodyl_point_right.pl ;
// finish adj_bodyl.pl. rotate points pi into their final correct location.
// note we rotate in the negative direction since adj_bodyl is the smallest-index
/ / adj acent body as i s "to-the-left-of-the-bendline-centerline" , which means
// rotating to the left.
// first, compute the right vector for the rotation line.
BM_VECTOR rot_v(cylinder->get_v() ) ; i f ( r o t _ v % ( (bendline_displayed_version->get_current_center_line () ) .get_v() ) < 0.0) { rot v.reverse () ;
} "
BM_rotate_point_around_line (_ (bend_bodyl_point_lef t .pi) , cylinder- >get_ptl () , rot_v,
-half_bend_arc_angle) ;
BM_rotate_point_around_line (Sc (bend_bodyl_point_right .pi) , cylinder- >get_ptl () , rot_v,
-half_bend_arc_angle) ;
// finish also adj_body2.pl. rotate points pi into their final correct location.
BM_rotate_point_around_line (Sc (bend_body2_point_lef t .pi) , cylinder- >get_ptl () , rot_v, half_bend_arc_angle) ;
BM_rotate_point_around_line (Sc(bend_body2_point_right .pi) , cylinder- >get_ptl () , rot_v, half_bend_arc_angle) ;
{ )
Figure imgf000521_0001
24 APPENDIX H else if (bop->is ( BM_TYPE_BEND OP_CONIC) )
{
// TODO : implement conic bendline here return 0 ;
} temp_v = -x^side_vectorl ; bend_bodyl_po i nt_l e f t . p bend_bodyl_point_left.pl + temp_v ; bend_bodyl_point_right . p bend_bodyl_point_right.pl + temp_v ;
// note : adj_bodyl.p2 and adj_body2.p, adj_body2.p2 are yet to be computed.
// now there are two cases : 1) the bend arc angle is acute (ie. no more than 90 degrees),
// 2) the bend arc angle is more than 90 degrees . if (bend_arc_angle > (PI_over_2 + BM_ANGLE_TOLERANCE) ) { // use tangent approximation
// we will finish computing adj_bodyl . adj_bodyl.p2 is left.
// idea : notice that adj_bodyl is to the left of the bendline-centerline
// because it is the lowest-index neighbor. Therefore the cross-product
// of centerline-v by temp_v points towards the cylinder (actually it is tangent
// to the cylinder) .
B M _ V E C T 0 R tangent_v(bend_bodyl_point_right .opening_direction ♦ temp_v) ; tangent_v.set_length(x) ; bend_body l_po int le f t . p2 bend_bodyl_point_left .p + tangent_v ; bend_bodyl_point_right .p2 bend_bodyl_point_right . p + tangent_v ;
// note adj_body2.pl is already computed, first set some common values. bend_body2_point_lef t . num_of _points = bend_body2_point_right .num_of_points = 3 ; bend_body2_point_left . can_reverse_opening_dir bend_body2_point_right . can_reverse_opening_dir = 0 ; bend_body2_point_right . opening_direct i on bend_bodyl_point_right .opening_direction ; bend_body2_po i nt_l e f . open i ng_d i re c t ion bend_bodyl_point_lef t . opening_direction ;
25 I
APPENDIX H
// now compute adj_body2.p temp_v = -x^side_vector2 ; bend_body 2 _po i n t _ 1 e f t . p bend_body2_point_left.pl + temp_v ; bend_body 2_po int_r ight . p bend_body2_point_right.pl + temp_v ;
// finally, compute adj_body2.p2
// note the order in the cross-product ! tangent_v = temp_v ♦ bend_body2_point_right . opening_direction ; tangent_v.set_length(x) ; bend_body 2_po i n t _ 1 e f t . p2 bend_body2_point_left .p + tangent_v ; bend_body2_point_r ight .p2 bend_body2_point_right .p + tangent_v ; else { // use intersection approximation // note : adj_body2.p2 is the same as asj_bodyl.pl . bend_body l_po in t_l e f t . p 2 bend_body2_point_left.pl ; bend_bodyl_point_right .p2 bend_body2_point_right.pl ;
// when using intersection approximation, dimensions points with respect to
// both adjacent bodies are the same, so we just copy them. bend_body2_point_left .num_of_points = bend_body2_point_right.num_of_points = 3 ; bend_body2_point_left . can_reverse_opening_dir bend_body2_point_right . can_reverse_opening_dir = 0 ; bend_body2_point_right . opening_direction bend_bodyl_point_right . opening_direction ; bend_body2_point_lef t . opening_direction bend_bodyl_point_lef t . opening_direction ;
// note we are switching points bend_body2_point_lef t . p2 bend_bodyl_point_lef t .pi bend_body2_point_r ight .p2 bend_bodyl_point_right .pi bend_body2_point_left . p bend_bodyl_point_left .p ,- bend_body2_point_right .p bend_bodyl_point_right -p
26 APPENDIX H
}
} break ; case BM_TYPE_CONE break ; default : ; // unknown or illegal surface ; }
/*
Compute flange length for each of the adjacent bodies. */ if (adj_bodyl) {
// if the flange length computation fails, pretend the adjacent body does not exist, for simplicity. i f- ( ! bend->compute_flange_length(parent->get_view_type () ,adj_bodyl, fll) )
{ adj_bodyl = NULL ;
--num of adjacent bodies ;
} ~ ~ if (adj_body2 ) { i f ( ! bend- >compute flange length (parent - >get_view_type ( ) , adj_body2 , f 12 ) )
{ adj_body2 = NULL ;
--num of adjacent bodies ;
» ' " ~ "
/*
Done. Mark data as valid. Once bendline dimension points have been computed for all bendlines, we can compute flange dimension points for all bendlines as well .
*/ data_valid = 1 ;
// before we can return, we have to check if bodyl, 2 left (right) bendline dimension points
// are the same.
// note the same means not the same pointers, but the contents are equivalent . if (adj_bodyl __ adj_body2) { bodyl2_left_the_same = (bend_bodyl_point_left
27 APPENDIX H bend_body2_point_left) ; bodyl2_right_the_same (bend_bodyl_point_right bend_body2 point_right) ;
/*
Important. If any of the bend-dimension points contains only
1 point (point p) , then the body_required_visible pointer should point to an adjacent body because there really is no bendline to see .
/ if (1 == bend_bodyl_point_lef t . num_of _points) bend_bodyl_point_left .body_required_visible = adj_bodyl ; if (1 == bend_bodyl_point_right . num_of _points ) bend_bodyl_point_right .body_required_visible = adj_bodyl ; if (1 == bend_body2_point_lef t . num_of _points ) bend_body2_point_left .body_required_visible = adj_body2 ; if (1 == bend_body2_point_right . num_of _points ) bend_body2_point_right .body_required_visible = adj_body2 ; return 1 ;
********** ********** ********** ********** ********** ********** ********** ********** **********
BM_AUTO_DIMENSION class stuff.
********** ********** ********** ********** **********
********** ********** ********** ********** */
SOLID HEURISTIC :
Check if we can ignore some points in solid mode. in solid mode we will be using this heuristic in order to save time. when two bendlines are using equivalent flange-dimension points for (potentially) displaying flange-length, we will only compute the visibility information only for the bendline (of these two bendlines) which has the higher idx.
*/ void BM_AUTO_DIMENSION: :compute_points_to_ignore_in_solid (void)
28 APPENDIX H int i ;
BM_AD_dim_corner temp_point ; for (i = 0 ,- i < num_of_bendlines ; i++) { if (! bends [i] ->data_valid) continue ; if (bends [i] ->adj_bodyl) { for (temp_point = bends [i] ->bodyl_points temp_point ; temp_point = temp_point->next) { if (NULL == temp_point->adj_bendline) continue if ( (temp_point->adj_bendline) ->get_idx() > (bends [i] ->bend) ->get_idx() ) continue ; i f
(check_two_bendlines_adjacent_to_same_flange (bends [i] ->bend,bends [i] ->adj_bodyl, temp_point->adj_bendline) ) { temp_point->ignore_in_solid_mode = 1 ;
if (bends [i] ->adj_body2) { for (temp_point = bends [i] ->body2_points ; temp_point ; temp_point = temp_point->next) { if (NULL == temp_point->adj_bendline) continue if ( (temp_point->adj_bendline) ->get_idx() > (bends [i] ->bend) ->get_idx() ) continue ; i f
(check_two_bendlines_adjacent_to_same_flange (bends [i] ->bend,bends [i] ->adj_body2, temp_point->adj_bendline) ) { temp_point->ignore_in_solid_mode = 1 ;
points to ignore in solid computed = 1 ;
} " "
/*
This function will build auto dimension bendline and point data structures .
This is the main function for computing dimension points. */ int BM_AUTO_DIMENSION: :compute_auto_dimension_data (void)
29 APPENDIX H
int l ;
// have to have a document if (NULL == doc) return 0 ;
// if no part, try to get a new part from the document if (NULL == part) { set_part (doc->get_part () ) ; if (NULL == part) { dirty = 0 ; return 1 ; } points_to_ignore_in_solid_computed = 0 ;
get view type if (view) { view_type = view->get_current_view0 else {
// we are screwed return 0 ;
}
I*
Compute all bendline dimension points for all bendlines. *I for (i = 0 ; i < num_of_bendlines ; i++) { bends [i] ->compute BM AD bendlineO ;
}
I*
Compute flange dimension points for every bendline.
*/ for (i = 0 ; i < num_of_bendlines ; i++) { if (bends [i] ->data_valid) { i f ( b e n d s [ i ] - > a d j _ b o d y l ) bends [i] ->compute_BM_AD_f lange_points (bends [i] ->adj_bodyl) ; i f ( b e n d s [ i ] - > a d j _ b o d y 2 ) bends [i] - >compute_BM_AD_f lange_points (bends [i] ->adj_body2) ;
dirty = 0 ; return 1 ;
30 APPENDIX I
//////////////////////////////////////////////////////////////
// //
// Example of some basic auto-dimensioning functions, //
// constructors, destructors and some other basic //
// functions. //
// //
// Copyright 1996 AmadaSoft America, Inc. //
// //
//////////////////////////////////////////////////////////////
#include "stdafx.h" #include "BendCAD.h" #include "BendCADDoc.h" #include "BendCADViewPart.h"
#include "AUTODIM.HXX"
/*
********** ********** ********** ********** **********
********** ********** ********** **********
BM_AD_dim_corner class stuff.
********** ********** ********** ********** **********
********** ********** ********** ********** */
BM AD dim corner: :BM AD dim_corner (void)
{ ~ " visible = -1 ; num_of_points = 0 ; bend = NULL ; next = NULL ; adj_bendline = NULL ; body_required_visible = NULL ; } ignore-in-solid-mode = 0 ;
/*
This constructor is for creating a dimension point that has only one point (point p) in it. */
BM_AD_dim_corner : : BM_AD_dim_corner (BM_POINT const- P, BM_AD_bendline B, BM_3D_BODY Body_required_visible,
BM_VECTOR constSL OD, int RB, BM_AD_dim_corner ♦♦prev, BM_BENDLINE adj_bend) visible = -1 ; num_of_points = 1 ; P = P ; APPENDIX I bend = B ; opening_direction = OD ; can_reverse_opening_dir = RB ; next = NULL ; body_required_visible = Body_required_visible ; adj_bendline = adj_bend ; ignore_in_solid_mode = 0 ,- if (prev) +prev = this ;
/*
This constructor is for creating a dimension point that has 3 points in it. */
BM_AD_dim_corner: :BM_AD_dim_corner(BM_P0INT const- P, BM_POINT constSc PI, BM_P0INT constSc P2,
BM_AD_bendline B, BM_3D_B0DY Body_required_visible, BM_VECTOR constSc OD, int RB, BM_AD_dim_corner ♦♦prev,
BM BENDLINE adj bend)
{ " visible = -1 ; num_of_points = 3 ; p = P ; pi = PI ; p2 = P2 ; bend = B ; opening_direction = OD ; can_reverse_opening_dir = RB ; next = NULL ; body_required_visible = Body_required_visible ; adj_bendline = adj_bend ; ignore_in_solid_mode = 0 ; if (prev) prev = this ; 51*
APPENDIX I
To assign one dimension point to another dimension point. This function copies the contents exactly, not sure if it is a very useful function.
7
Figure imgf000530_0001
can_reverse_opening_dir = given_point.can_reverse_opening_dir
; visible = given_point.visible ; screen_x = given_point.screen_x ; screen_y = given_point.screen_y ; z_buf_value = given_point.z_buf_value ; ignore_in_solid_mode = given_point.ignore_in_solid_mode ;
/* this function will return TRUE iff the given point is, for the purpose of drawing dimensions, the same as this point.
Two dimension points points are equivalent iff the point p of one of them is on the line defined by the line (point p, opening direction) of the other dimension point, and their opening directions match. here we depend on the fact that opening vectors are normalized. it returns 2 iff both points p match, otherwise 1. */ int BM_AD_dim_corner: :operator== (BM_AD_dim_corner const- another dim point)
{ " " int ret_val = 1 ; double k ; if (num_of_points < 1 | | another_dim_point.num_of_points < 1) return 0 ; APPENDIX I
// point has to be on the line if ( ! BM_is_point_on_line (p, opening_direction, another_dim_point.p, _k) ) return 0 ; if (fabs(k) <= BM_PRECISION) ret_val = 2 ; is %
be
| j
Figure imgf000531_0001
return 0 ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
BM_AD_bendline class stuff.
********** ********** ********** ********** **********
********** ********** ********** ********** */
BM_AD_bendline : :BM_AD_bendline (BM_AUTO_DIMENSION owner, BM BENDLINE bendline)
{ " parent = owner ; bend = bendline ; data_valid = 0 ; // data not valid - no data computed yet bend_bodyl_point_left .bend = bend_bodyl_point_right .bend = this ; bend_body2_point_left .bend = bend_body2_point_right .bend = this ; bend_bodyl_point_left . body_required_visible bend_bodyl_point_right .body_required_visible = bend ; bend_body2_point left . body_required_visible bend_body2_point_right .body_required_visible = bend ; bodyl_points = NULL ; body2_points = NULL ; APPENDIX I }
BM AD bendline : : ~BM AD bendline (void)
{ " "
BM_AD_dim_corner temp_point, temp_p ;
// delete lists of points for (temp_point = bodyl_points ; temp_point ; temp_point = temp_p) ( temp_p = temp_point->next ; delete temp point ;
} for (temp_point = body2_points ; temp_point ; temp_point = temp_p) { temp_p = temp_point->next ; delete temp point ;
}
}
/*
********** ********** ********** ********** **********
********** ********** ********** **********
BM_AUTO_DIMENSION class stuff.
********** ********** ********** ********** **********
********** ********** ********** ********** */
BM AUTO DIMENSION: :BM AUTO DIMENSION(CBendCADDoc BendCAD doc)
{ " doc = BendCAD_doc ; v i e w = ( C B e n d C A D V i e w P a r t ) doc->get_view(BENDCAD_VIEW_TYPE_PART) ; dc = NULL ; part = NULL ; dirty = 1 ; view_type = 1 ; // 3D view reset_view_to_false_once_drawn = 0 ; points_to_ignore_in_solid_computed = 0 ; num_of_bendlines = 0 ; bends = NULL ;
// initialize show states for dimension info
5 APPENDIX I m_bShowFlangeDim = TRUE; m_bShowBendDim = TRUE; m_bShowPartDim = FALSE;
// initialize Auto-Dim colors m_crFlange = RGB (0, 0, 255) ; m_crBend = RGB (0, 0,255) ; m_crPart = RGB (0, 0, 255) ;
// initialize font pointers m_pFlangeFont = NULL; m_pBendFont = NULL; m_pPartFont = NULL;
// initialize line and arrow styles m_nLineStyle = PS_SOLID; m_nLineWeight = 1; // in pixels m_nArrowStyle = 1,- m_nArrowAngle = 30; // in degrees m_nArrowLength = 15; // in pixels
// initialize dirty region pointer pDirtyRegion = NULL;
BM AUTO DIMENSION: :-BM AUTO DIMENSION(void)
{ " " " delete contents () ;
}
/* destroy the contents of this Auto-Dimension object, */ void BM_AUTO_DIMENSION: :delete_contents (void) int i ; if (bends) { for (i = 0 ; i < num_of_bendlines ; i++) ( if (bends [i] ) delete bends [i] ; delete [] bends ; bends = NULL ;
} num_of_bendlines = 0 ; points_to_ignore_in_solid_computed = 0 ;
6 .
APPENDIX I part = NULL ; dirty = 1 ;
/*
This function returns a pointer to the BM_AD_bendline structure that contains dimensions data associated with the given bendline.
*/
B M _ A D _ b e n d l i n e
♦BM AUTO DIMENSION: :get_AD_bend_structure (BM_BENDLINE bendline)
{ int i ; for (i = 0 ; i < num_of_bendlines ; i++) ( if (bends [i] ->bend == bendline) return bends [i] ;
} return NULL ;
/*
This function returns a a (p->p2) vector for a given bendline with respect to a given adj -body.
It also computes a line between the p2 points of the bend dimension points of the adjacent bendline with respect to this flange. */
B M _ V E C T O R c o n s t -
BM_AUTO_DI ENSION: : compute_bend_direction_vector (BM_BENDLINE bendline, BM 3D BODY ^adj body, BM LINE ^p2 line) { " " - - - static BM_VECTOR v ; int i ; for (i = 0 ; i < num_of_bendlines ; i++) { if (bends [i] ->data valid ScSc bends [i] ->bend == bendline)
{ if (bends [i] ->adj_bodyl == adj_body) { v = (bends [i] ->bend_bodyl_point_left) .p2 (bends [i] ->bend_bodyl_point_left) .p ; p2_line->set ( (bends [i] ->bend_bodyl_point_left) .p2, (bends [i] ->bend _bodyl_point_right) .p2) ; return v ;
} else if (bends [i] ->adj_body2 == adj_body) { APPENDIX I v = (bends[i] ->bend_body2_point_left) .p2 (bends [i] ->bend_body2_point_left) .p ; p2_line->set ( (bends [i] ->bend_body2_point_left) .p2, (bends [i] ->bend _body2_point_right) .p2) ; return v ;
return BM_null_vector ; }
/*
This function is used to propagate the effects of drawing a flange length for a given bendline, to account for the fact that the flange dimension point is adjacent to the given adj-body. it returns TRUE iff the adj-bend will be marked as drawn as well with respect to the given flange. */ i n t BM_AUTO_DIMENSION: :compute_effects_flange_length_drawn(BM_BENDLINE ♦bendline, BM_3D_B0DY adj_body,
BM_AD dim_corner bend_dim_point /♦ bend dim point for bendline *~J ,
BM_AD dim_corner ♦flange_dim_point /♦ flange dim points for bendline *"] ,
BM BENDLINE ♦adj bend)
{
BM_AD_dim_corner ♦♦p_body_points ; int p_body_drawn ;
BM_AD_dim_corner ♦♦p_drawn_bend_dim_point ;
BM_AD_dim_corner ♦♦p_drawn_flange_dim_point ; int i ;
// first we have to find a BM_AD_bendline structure for this adj-bend for (i = 0 ; i < num_of_bendlines ; i++) { if (! bends [i] ->data_valid | | bends [i] ->bend != adj_bend
I I bends [i] ->ignore) continue ; if (bends [i] ->adj_bodyl == adj_body) { if (bends[i] ->bodyl_drawn) return 0 ; p_body_points = Sc(bends [i] ->bodyl_points) ; p_body_drawn = Sc(bends [i] ->bodyl drawn) ; APPENDIX I p _ d r a w n _ b e n d _ d i m _ p o i n t Sc (bends [i] ->drawn_bend_dim_pointl) ; p _ d r a w n _ f l a n g e _ d i m _ p o i n t Sc (bends [i] ->drawn_f lange_dim_pointl) ; break ; else if (bends [i] ->adj_body2 == adj_body) { if (bends [i] ->body2_drawn) return 0 ; p_body_points = Sc(bends [i] ->body2_points) ; p_body_drawn = Sc(bends [i] ->body2_drawn) ; p _ d r a w n _ b e n d _ d i m _ p o i n t Sc (bends [i] ->drawn_bend_dim_point2) ; p _ d r a w n _ f l a n g e _ d i m _ p o i n t Sc (bends [i] ->drawn_f lange_dim_point2) ; break ;
} else return 0 ;
} if (i >= num_of_bendlines) return 0 ;
// now we need to check if the list of flange dimension points for this newly found
// BM_AD_bendline structure contains any flange dimension points that are adjacent to our bendline
BM_AD_dim_corner temp_point ; for (temp_point = p_body_points ; temp_point ; temp_point = temp_point->next) { if (temp_point->adj_bendline == bendline) break ; if (NULL == temp_point) return 0 ;
// mark the flange length for the adj -bend drawn with respect to this adj-body
♦p_body_drawn = 1 ;
♦p_drawn_bend_dim_point = flange_dim_point ;
♦p_drawn_flange_dim_point = bend_dim_point ; return 1 ; }
/* this function will return TRUE iff adj_bend has a flange-dimension point with respect to the given flange, that is adjacent to the given bendline.
*/ i n t BM_AUTO_DIMENSION: : check_two_bendlines_adjacent_to_same_f lange (BM BENDLINE bendline, APPENDIX I BM_3D_BODY ♦flange, BM_BENDLINE adj send) BM_AD_dim_corner ♦♦p_body_points ; int i ;
// first we have to find a BM_AD_bendline structure for this adj -bend for (i = 0 ,- i < num_of_bendlines ; i++) { if (! bends [i] ->data_valid | | bends [i] ->bend != adj_bend) continue ; if (bends [i] ->adj_bodyl == flange) { p_body_points = Sc(bends [i] ->bodyl_points) ; break ;
} else if (bends [i] ->adj_body2 == flange) { p_body_points = Sc (bends [i] ->body2_points) ; break ;
} else return 0 ,-
} if (i >= n_m_of_bendlines) return 0 ;
// now we need to check if the list of flange dimension points for this newly found
// BM_AD_bendline structure contains a flange dimension points that is adjacent to our bendline
BM_AD_dim_corner temp_point ; for (temp_point = p_body_points ; temp_point ; temp_point = temp_point->next) { if (temp point->adj bendline == bendline) return 1 ,-
} return 0 ;
}
/*
To set a new part. This updates the view class pointer as well and sets some other parameters. */ void BM_AUTO_DIMENSION: :set_part (BM_PART ♦new_part)
BM_BENDLINE bendlist ; int i ; delete_contents () ; if (NULL == doc) return ;
10 APPENDIX I part = new_part ; if (NULL == part) return ; half_metal_thickness = (part->get_metal_thickness () ) /2.0 ;
// allocate the bendlist if (0 == (num_of_bendlines = part->get_number_of_bendlines () ) ) return ; if (NULL == (bends = new BM_AD_bendline^ [n_rr_of_bendlines] ) ) goto failure ; bendlist = part->get_bendline_list () ; for (i = 0 ; i < num_of_bendlines ; i++) ( if (bendlist) { bends [i] = new BM_AD_bendline (this,bendlist) ; bendlist = (BM BENDLINE ) bendlist->next () ;
} else bends [i] - NULL ;
} // note, dirty is TRUE return ; failure : delete_contents () ;
}
11 APPENDIX J
UUUUUUUUU//U/////UUUUIUUU/U//UUUUIUUU i ItI Example of bend model viewer implementation including I/I/ // entity visibility function for sheet metal part. //
// //
// Copyright 1996 AmadaSoft America, Inc. //
#include m"sitld nafxu.h u"iiu/u/iium iiiiiiu Him i/i/i ut i ut it
// include all BMAPI files #include "ALLBMAPI .HXX"
// RW_DRAW library include file. #include "RW_DRAW.HXX"
#include "BendCADDoc.h" #include "BendCADViewPart .h"
// RenderWare include files; found in \rwwin\include #include "rwlib.h"
// OpenGL include files. #include "gl\gl.h" #include "gl\glu.h"
// GL_LIST library include file. #include "GL_LIST.HXX"
#include <stdlib.h>
/*
Given a BM_POINT, which represents a point in world coordinates, one can project it onto view window coordinates.
A) If the display is showing the SOLID version of the part, this function passes back a pointer to the edge closest to the camera that lies under that projected point. The x_pos, y_pos, and z_depth pointers carry the view window coordinates (with top left corner as (0,0) and the z-buffer value.
If the projected point is not in the viewing volume, the return value is 0; then of course the edge pointer is meaningless, and is set to NULL. If the projected point IS within the viewing volume, then the return value is 1, and the edge pointer points to the edge that lies under the projected point.
If the pointer is NULL, no edge lies under the projected point. APPENDIX J
B) If the display is showing the WIREFRAME version of the part, only the return value: 1 if within view volume, 0 otherwise - should be examined. If return value is 1, x_pos, y_pos and z_depth values have meaning. The edge pointer is always NULL.
*/ int CBendCADViewPart : :map_point_to_closest_edge (BM_P0INT const- three_d_point, int x_pos, int y_pos, double z_depth, BM EDGE ♦♦closest_edge) { " int x, y, visible = 1; double z; visible = map_3d_to_screen (three_d_point, _x, Scy, Scz) ; if ( ! visible ) ( // Point is outside viewing volume . if (closest_edge) ♦closest_edge = NULL; if (x_pos) x_pos = x; if(y_pos) y_pos = y; if (z_depth) z_depth = z; return 0;
}
// Now point is inside view volume. if (x_pos) x_pos = x; if (y_pos) y_pos = y; if (z_depth) ♦z_depth = z; if ( ! mi_show_solid) { // Wireframe being drawn; just return that point is if (closest_edge) closest_edge = NULL; // within view vol. return 1;
}
// Now solid is being shown, if ( ! closest_edge) return 1;
// Point is within view volume. Pick that point. pick_point_rw(x, y, closest_edge) ; return 1;
}
// This function returns the view window coordinates of a point, with top left corner as (0,0) , and the
// z-buffer depth, given the three-dimensional world coordinates of the point. It does so by calling either APPENDIX J
// map_3d_to_screen_solid or map_3d_to_screen_wire, depending on whether wireframe or solid is being shown.
// On return, iff ♦x_pos, y_pos are both zero, the point was not mapped onto the screen at all. int CBendCADViewPart: :map_3d_to_screen(BM_P0INT three_d_point, int
♦x pos, int ♦y pos, double z_depth)
{ " int visible; if (mi_show_solid) visible =map_3d_to_screen_solid(three_d_point, x_pos, y_pos, z_depth) ; else visible = map_3d_to_screen_wire (three_d_point, x_pos, y_pos, z_depth) ; return visible;
}
// This function returns the view window coordinates of a point, with top left corner as (0,0) , and the
// z-buffer depth, given the three-dimensional world coordinates of the point, using OpenGL utilities
// (ie. when wireframe is on) . If return value is 0, point is not mapped onto screen, ie. not visible. int CBendCADViewPart: :map_3d_to_screen_wire (BM_POINT three_d_point, int x_pos, int y_pos, double z_depth)
int viewport [4] , visible = 1; double width, height, depth; double model_mat [16 ] , proj_mat [16] , array [16] ;
// Get the current viewport coords. glGetIntegerv(GL_VIEWPORT, viewport) ;
// Now build a modelview matrix out of the current set of transformations. glMatrixMode (GL_MODELVIEW) ; glPushMatrixO ; glTranslated(md_x_trans, md_y_trans, 0.0); convert_rw_matrix_to_gl_array(md_rot_matrix, array) ; glMultMatrixd(array) ; glTranslated(- m_part_centroid.X() , - m_part_centroid.Y() , - m_part_centroid.Z() ) ; glGetDoublev(GL_MODELVIEW_MATRIX, model_mat) ; glGetDoublev(GL_PROJECTION_MATRIX, proj_mat) ; glPopMatrixO ; gluProject (three_d_point .X () , three_d_point .Y( ) , three_d_point.Z () , model_mat, proj_mat, viewport, -width, -height, -depth) ; if( ( (int)width > m_old_rect.right) | | ((int)width < 0) ) visible = 0; APPENDIX J if ( (dnt)height > m_old_rect .bottom) | | ((int)height < 0) ) visible = 0; if(x_pos) x_pos = (int) width; if(y_P°s) *y_Pθs = (m_old_rect.bottom - (int) height) ; if(z_depth) z_depth = depth; return visible; }
// This function returns the view window coordinates of a point, with top left corner as (0,0) , and the
// z-buffer depth, given the three-dimensional world coordinates of the point, using RenderWare utilities
// (ie. when solid is on) . If return value is 0, point is not mapped onto the screen, ie. not visible.
// Note: At present, same as map_3d_to_screen_wire. int CBendCADViewPart: : map_3d_to_screen_solid (BM_POINT three_d_point, int x_pos, int *y_pos, double z_depth)
int viewport [4] , visible = 1; double width, height, depth; double model_mat [16] , proj_mat [16] , array[16] ;
// Get the current viewport coords. glGetIntegerv(GL_VIEWPORT, viewport) ;
// Now build a modelview matrix out of the current set of transformations. glMatrixMode (GL_MODELVIEW) ; glPushMatrixO ; glTranslated(md_x_trans, md_y_trans, 0.0) ; convert_rw_matrix_to_gl_array(md_rot_matrix, array) ; glMultMatrixd(array) ; glTranslated(- m_part_centroid.X() , - m_part_centroid.Y() , - m_part_centroid.Z () ) ; glGetDoublev(GL_MODELVIEW_MATRIX, model_mat) ; glGetDoublev(GL_PROJECTION_MATRIX, proj_mat) ; glPopMatrixO ; gluProject (three_d_point .X () , three_d_point .Y () , three_d_point .Z () , model_mat, proj_mat, viewport, -width, Scheight, Scdepth) ; if ( ((int)width > tr_old_rect .right) | | ((int)width < 0) ) visible = 0; if ( ((int)height > m_old_rect.bottom) ] | ( nt)height < 0) ) visible = 0; if(x_pos) x_pos = (int) width;
4 APPENDIX J if(y_pos) ♦y_pos = (m_old_rect .bottom - (int) height) ; if(z_depth) ♦z_depth = depth; return visible;
// This function picks the point indicated by map_3d_to_screen, using RenderWare picking, so this is
// called only when solid is being shown. Note that the pick position is with respect to the top left
// corner of the view window being (0,0) . If the pick results in an edge, a pointer to the edge is
// passed back in picked_edge; else, picked_edge is set to null.
This does not modify the selection
// set in any way. void CBendCADViewPart : :pick_point_rw(int x_pos, int y_pos, BM_EDGE
♦♦picked edge)
{ if (picked_edge == NULL) return;
if( (x_pos > m_old_rect.right) j j (y_pos > m_old_rect .bottom) ) { // Make sure point given is within picked_edge = NULL;
// viewport, return;
}
RwClump picked_clump = NULL; RwClump parent_clump = NULL; long parent_tag, clump_tag, key = 0; BM_EDGE edge = NULL; if ( ! RwPickScene (m_scene, x_pos, y_pos, m_camera, _m_pick) ) { // Picking command was not successful. picked_edge = NULL; return;
} if (m_pick.type == rwNAPICKOBJECT) { // No clump was picked.
picked_edge = NULL; return;
} else if (m_pick.type == rwPICKCLUMP) { // Some clump was picked; process it. APPENDIX J picked_clump = m_pick.object.clump.clump; parent_clump = RwGetClumpParent (picked_clump) ; parent_tag = RwGetClumpTag(parent_clump) ; clump_tag = RwGetClumpTag(picked_clump) ; if (parent_tag == 1) { ♦picked_edge = NULL; return; // A trivial bendline or forming was picked.
}
// Now some real edge was picked. key = (parent_tag%10000) lOOOOO + clump_tag; if (clump_tag) /
Safety check; we expect clump_tag to be non-zero.
♦picked_edge = map_list_name_to_bm_edge (parent_tag, clump tag) ;
} "
}
// This function returns the ratio of the view volume dimension
(object space dimensions) to
// the viewport dimension (device space dimensions) . double CBendCADViewPart: :get_object_to_device_ratio (void)
{ double ratio; if (m_old_rect.right) ratio = 2.O^md_current_view_vol [0] / (double) (m_old_rect.right) ; else ratio = 0.0; return ratio;
}
/*
Given a BM_POINT, which represents a point in world coordinates, one can project it onto view window coordinates. This function first checks if the projected point is within the viewing volume. If it IS within viewing volume, the pointer "visible" carries value 1; else, 0. If the point is not visible, no other parameters have any meaning; the return value is 0.
Now suppose the point is visible.
A) If the display is showing the SOLID version of the part, this function checks if ANY of the three_d_bodies in the array "three_db_array" lies "approximately under" the projected point . If the answer is yes, return value is 1; else, return value is zero. The x_pos, y_pos, and z_depth pointers carry the view window coordinates (with top left corner as (0,0)) and the z-buffer value. APPENDIX J
The array "thee_db_array" must be terminated by a NULL pointer to indicate end of array.
B) If the display is showing the WIREFRAME version of the part the return value is always zero. If the point is within view volume, ♦visible is set to 1; else, 0. If visible is 1, x_pos, y pos and z_depth values have the meaning mentioned above.
*7 int CBendCADViewPart : :is_3d_body_near_point (BM_P0INT const- three_d_point, BM_3D_B0DY ♦♦three_db_array, int visible, int ♦x_pos, int ♦y pos, double z_depth)
{ int x, y, is_visible = 1; double z; int found = 0; is_visible = map_3d_to_screen(three_d_point, _x, Scy, Scz) ; if ( ! is_visible) { // Point is outside viewing volume. if (x_pos) x_pos = x; if(y_pos) y_pos = y; if (z_depth) z_depth = z; if (visible) visible = 0; return 0;
}
// Now point is inside view volume, if (x_pos) x_pos = x; if (y_pos) y_pos = y; if(z_depth) z_depth = z; if (visible) visible = 1; if ( ! mi_show_solid) { // Wireframe being drawn; just return that point is return 1;
// within view volume. }
// Now solid is being shown, if ( ! three_db_array) return 0;
// Point is within view volume. Pick pixels in a triangle around that point . found = pick_point_for_3db_rw( (x - 2), (y - 2) , three_db_array) ; if (found) return 1; found = pick_point_for_3db_rw( (x - 2) , (y + 2) , three_db_array) ; if (found) return 1; APPENDIX J found = pick_point_for_3db_rw( (x + 2) , (y + 2) , three_db_array) ; if (found) return 1; found = pick_point_for_3db_rw( (x + 2), (y - 2) , three_db_array) ,- if (found) return 1; return 0;
// This function picks the point indicated, using RenderWare picking, so this is called only when solid is
// being shown. Note that the pick position is with respect to the top left corner of the view window being
// (0,0) . If the pick results in a three_d_body' s clump, and the picked clump corresponds to ANY of the
// three_d_bodies in the array passed, return value is 1; if no match or no three_d_body, return is 0.
// This does not modify the selection set in any way. int CBendCADViewPart : :pick_point_for_3db_rw(int x_pos, int y_pos,
BM 3D BODY ♦♦three db array)
{ if (three_db_array == NULL) return 0;
if ( (x_pos > m_old_rect .right) | | (y_pos > m_old_rect .bottom) ) { // Make sure point given is within return 0; // viewport.
}
RwClump picked_clump = NULL; RwClump parent_clump = NULL; long parent_tag, clump_tag, required_id; int found = 0; if ( ! RwPickScene (m_scene, x_pos, y_pos, m_camera, _m_pick) ) ( // Picking command was not successful . return 0;
} if (m_pick.type == rwNAPICKOBJECT) { // No clump was picked. return 0;
} else if (m_pick.type == rwPICKCLUMP) { // Some clump was picked; process it. picked_clump = m_pick.object.clump.clump; APPENDIX J parent_clump = RwGetClumpParent (picked_clump) ; parent_tag = RwGetClumpTag(parent_clump) ; clump_tag = RwGetClumpTag(picked_clump) ; if (parent_tag == 1) {
// Body of face/bendline/forming was picked, for(int i=0; three_db_array[i] ,- ++i) { // Check if it matches any of the ones in array, if (three_db_array[i] == NULL) break; required_id = three_db_array[i] ->get_idx() ; if (clump_tag%10000 == required_id) ( found = 1; break; }
} return found;
}
// Now some edge's clump was picked. Check if it matches any of the ones in array. fordnt i=0; three_db_array[i] ,- ++i) { if (three_db_array[i] == NULL) break; required_id = three_db_array[i] ->get idx() ; if (parent_tag%10000 == required_id) found = 1; break;
, ' ' return found; }
// This allows the user to insert items into the selection set.
"list" is an array of pointers
// to three-d-bodies, terminated by NULL to indicate end of array.
If list is passed as NULL, every
// three-d-body in the part is inserted into the selection set. void CBendCADViewPart : :insert_selection_set (BM_3D_B0DY ♦♦list)
int tag;
BV_SELECT_DATA data = NULL; if ( ! list) { // Insert every three_d_body in part into selection set.
BM_PART part = NULL; CBendCADDoc^ pDoc = GetDocument () ; ASSERT_VALID(pDoc) ; part = pDoc->get_part 0 ; APPENDIX J if ( ! part) return; BM_FACE face = NULL;
BM_BENDLINE bendline = NULL; BM_FORMING forming = NULL; for(face = part->get_face_list 0 ; face; face (BM FACE ♦) face->next 0 ) { if ( ! face) continue; tag = 100000+ (face->get_idx() ) + 10000 face->get_idx() ; if ( ! m_selection_set. find(tag, NULL)) { data - new BV_SELECT_DATA; data->key = tag; data->edge = NULL; data->world_pt = BM_POINT (0.0, 0.0, 0.0) ; m_selection_set . insert (tag, (long) data) ;
}
} for (bendline = part->get_bendline_list 0 ; bendline; bendline = (BM_BENDLINE )bendline->next () ) { if ( ! bendline) continue; tag = 100000+ (bendline->get_idx() ) + 10000 + bendline->get_idx() ; if ( ! m_selection_set . find(tag, NULL)) { data = new BV_SELECT_DATA; data->key = tag; data->edge = NULL; data->world_pt = BM_POINT (0.0, 0.0, 0.0) ; m_selection_set. insert (tag, (long)data) ;
}
} for (forming = part->get_forming_list () ; forming; forming = (BM_FORMING ) forming->next 0 ) { if { ! forming) continue; tag = 100000+ (forming->get_idx() ) + 10000 + forming->get_idx() ; if ( ! m_selection_set. find(tag, NULL)) { data = new BV_SELECT_DATA; data->key = tag; data->edge = NULL; data->world_pt = BM_POINT(0.0, 0.0, 0.0) ; m_selection_set . insert (tag, (long) data) ;
} }
DrawPart (m_hdc) ; return;
10 APPENDIX J
BM_3D_BODY *three_d_body; long i; for ( i=0 , three_d_body = list [ 0] ; three_d_body ; ++i , three_d_body = list [ i] ) { if ( ! three_d_body) break; tag = 100000+ (three_d_body->get_idx() ) + 10000 + three_d_body->get_idx() ; if ( ! m_selection_set. find(tag, NULL)) { data = new BV_SELECT_DATA; data->key = tag; data->edge = NULL; data->world_pt = BM_POINT(0.0, 0.0, 0.0) ; m selection set.insert (tag, (long)data) ;
}
}
DrawPart (m_hdc) ; return;
}
// This function returns the largest of the x, y and z projections of the part's
// bounding box. double CBendCADViewPart: :get_approx_part_size (void)
{ if (md_part_bbox_size) { double size = max ( md_pa t_bbox_s i z e [ 0 ] , md_part_bbox_size [1] ) ; size = max(size, md_part_bbox_size [2] ) ; return size;
} else return 0.0;
}
// This function passes back the bounding box size of the part in its original orientation, in the
// array "dimensions". This array should be at least of size 3.
Returns 1 if successful, 0 otherwise.
// Caution: This is a quick and hence not very accurate calculation; if you want greater precision,
// write your own function. int CBendCADViewPart ::get part dimensions (double *dimensions)
{ " "
CBendCADDoc* pDoc = GetDocument () ; if ( ! pDoc) return 0;
BM_PART *part = pDoc->get_part () ; if ( ! part) return 0,- if ( ! dimensions) return 0;
11 APPENDIX J
int i;
BM_POINT centroid;
RwMatrix4d *temp = RwCreateMatrix() ; i = compute_part_centroid(part, 1, -centroid) ; if ( ! i) return 0; compute_part_bbox (part, 1, temp, centroid, dimensions, NULL) ; if ( ! i) return 0; RwDestroyMatrix(temp) ; return 1;
12 APPENDIX K minimum mmimuimuimmmiiiiuiuiummiii ι Uι PART.HXX comments on Bend Model and part structure, etc. '//,
// //
// Copyright 1996 AmadaSoft America, Inc. //
// //
////////////////////////////////////////////////////////////////
/ *
This file contains BMAPI BM_PART class definitions.
Most of the part functions are in PART.CPP.
Constructors and destructors are in PART_NEW.CPP.
Serialization functions are in PART_LOAD_x.CPP and
PART_SAVE.CPP.
Folding functions are in FOLD.CPP and 3D_FUNC.CPP.
Unfolding functions are in UNFOLD.CPP.
***** ******** ********* ********* ********* ********* ********* Discussion :
- One of the design principles of BMAPI is that we want to represent the entire part accurately, with thickness and everything. One of the advantages of this is that we can query anything and get an answer quickly. Even if the answer is not explicitly represented, it is easy to compute. Another advantage of that is that it is straightforward to 3D modelling with the part, since we are representing the part "as a solid part".
- One of the special properties of sheetmetal is that it is symmetric. We can take anvantage of this fact when we represent and reason about the part. For example, we can represent only one side of the sheetmetal, since the other side of the sheetmetal is defined once we know the thickness vector.
- One issue is if we are given a flat version of the part (which usually does not include thickness) , how do we construct the part from that. Do we take that this flat represents the neutral line of the part? In this BMAPI we have taken that the flat version of the part that is explicitly represented in the bend model is the BOTTOM side of the sheetmetal when the part is in TOP VIEW. Another important point is that this flat version is on the X-Y plane. This way even if the thickness changes, changes to our model are minimal.
- Although the flat represents the BOTTOM side of sheet-metal, the dimensions of flat represent neutral-line dimensions. That is, when we bent the part, the neutral-line dimensions of the bent part match the flat dimensions (or are off by an amount defined by the APPENDIX K bend deduction) . This is irrelevant for faces since for them inside=neutral-line=outside. However, it is important for bendlines. That means that the underlying flat of a bendline is mapped onto neutral line of the bend arc.
- When a part is folded, BMAPI normally does not change the 2D->3D transformation of the base-body. However, when the base-body is a bendline and the user has changed some of the bend parameters (for instance, bend angle) the 2D->3D transformation matrix is marked as 'not-up-to-date' . If we used this old transformation matrix, the results would be worng. Therefore we cannot really use the old (out-of-date) transformation matrix. But in that case we don't have anything better to do than to reset the transformation matrix to an identity matrix.
- The size of every 3D body can change in two ways. First, if a face has an adjacent bendline whose bend deduction is non-zero, the face is trimmed by an amount equal to half of the bend deduction. Second, every body can have a trimming value associated with it with respect to an adjacent bendline. When the adjacent bendline is being bent, this body is trimmed by this amount.
- BM API can load all known (ie. latest and all earlier) versions of BMAPI files. However, it saves only in the latest file format .
- When a part is folded, only 2D->3D transformations are computed right away. The rest of the computations is done on demand, ie. whenever needed. When we unfold a part, everything is computed right away, ie. 3D-2D transformations and the flat version of the part.
- When a part is unfolded, BMAPI will use the current 3D-version of 3D-bodies, regardless of whether they are marked as up-to-date or not.
- BM_PART class contains several highlevel functions to facilitate part creation. For example, it contains functions that will inpect the flat version of the part and fix any problems found. Also, it contains functions for creating bendlines for the part when only a set of faces is given. These are high-level functions that are common tasks in many applications.
- For bendlines of the part it is absolutely necessary that they have a centerline specified. Without the centerline, a bendline is almost useless, it cannot be folded or unfolded. Bendline centerline is used for three purposes :
- for bendline folding-unfolding.
- for representing the bendline when the bendline is empty. APPENDIX K
- for determining the bendline orientation.
Notice that the centerline is the most "objective" in the 2D (ie. flat) version of the part, since the flat version has a fixed orientation (ie. normal has to be (0,0,1) ) . In 3D version of the part, centerline is somewhat "subjective" since its meaning is defined by the underlying surface, which can change. For example, we can flip the surface (which necessarily does not change the (sheet-metal) part and as a result have to reverse the centerline as well in order to keep the bendline orientation the same.
- Every bendline has a bend deduction associated with it. This bend deduction controls how part dimensions (at this bendline) change when the part is folded or unfolded. The bend deduction value can be both the positive and negative. When it is positive and we fold the part, then the part dimensions will expand, when it is negative then part dimensions will shrink. (I was told that) it is the industry standard that positive bend deduction means expanding part when folding and shrinking part when unfolding, and accordingly, negative bend deduction means shrinking part when folding and expanding part when unfolding.
- A BM_PART has a parameter bendline_dimensions_status which controls the part dimensions. It is added to facilitate part desing and creation. It is the case often, that the user is given the part dimensions, from outside to outside (for example) . These dimensions are fixed and specified by the customer. The goal of a sheet-metal desing process is to produce a flat of this part so that when this flat is folded its dimensions exactly match the given dimensions. In the design process the user can change the part is a number of ways. However, given this, we always want to keep the part dimensions unchanged.
If bendline_dimensions_status is TRUE, BMAPI will try to keep to part dimensions (at every bendline) constant whenever possible, when the user changes the part/bendline parameters dike, metal thickness, or bendline raidus, etc.) . Otherwise we don't care.
- Another issue that comes up in conjunction with the previous issue is that part dimensions are usually specified as OUTSIDE/INSIDE/NEUTRAL dimensions. For example, the user specifies that given a box, the outside dimensions of the box are 100x100. Technically the user is specifying that on the flat every bendline in this box represents outside dimensions. For example, when the user later changes the metal thickness, outside dimensions have to remain the same, ie. all the added thickness "has to go inside the box". In general, the user (or customer) might specify part dimensions as OUTSIDE/INSIDE/NEUTRAL dimensions, even in the same face. For example, the user might say that across the box, the APPENDIX K dimensions are given as from the inside side of the metal of one side to the outside side of the metal on the other side.
We have a variable in the part to keep track whether the user wants to keep the part dimensions constant or not. If this variable is set so that the user does not require that the part dimensions be kept constant, this while business of INSIDE/OUTSIDE/NUETRAL-LINE is ignored.
*/
#ifndef BM_PART_HXX_INCLUDED #define BM_PART_HXX_INCLUDED
#include <stdio.h>
#include "GLOBAL.HXX" #include "ENTITY.HXX" #include "TOPOLOGY.HXX" class BM PART : public BM ENTITY
{ friend BM_FACE ; friend BM_HOLE ; friend BM_BENDLINE ; friend BM_FORMING ; friend BM_TOPOLOGY ; friend BM_TOPOLOGY_RECORD ; friend BM_BEND_PROPERTY ; friend BM_BEND_PROPERTY_SIMULTANEOUS ;
// every part has a (user-defined) name that it inherits from BM_ENTITY.
// also, the type (BM_ENTITY_TYPE_PART) is stored in BM_ENTITY. protected :
/*
These variables let the user associate parameters, like a name, number, material type, with the part.
*/ char material_type [256 ] ; char name [256] ; char number [32 ] ;
/* APPENDIX K
These variables describe material and metal properties.
*/ double metal_thickness ;
/*
Within this part, two points are considered to be the same if the distance between them is no more than this value .
*/ double distance_tolerance ;
/*
Every part has a list of bend properties. If a bendline has a bend property, this property object has to be on the list of bend properties associated with the part.
This is needed when we save or load a part.
These variables are used only internally. The user of BMAPI has no access to these variables.
*/ long number_of_bend_properties ; BM_BEND_PROPERTY *list_of_bend_properties ;
/'
Part topology.
Note that it is not possible to directly add bodies to the lists here.
This is done only when a body is added to the part topology.
7
BM_TOPOLOGY topology ;
// number of different 3D bodies in the part .
// these numbers should be consistent with the part topology. long number_of_faces ; long number_of_holes ; long number_of_bendlines ; long number_of_formings ;
// lists of faces, holes and bendlines of the part // Note that these are lists of BM_3D_B0DY's. BM_FACE *first_face ; BM_HOLE *first_hole ; BM_BENDLINE +first_bendline ; BM_FORMING *first_forming ;
/*
These parameters represent a bend sequence associated with the part APPENDIX K
*/ long bend_sequence_size ; BM_LINKED_LIST_NODE +bend_sequence ;
/*
This parameter controls part dimensions. If it is TRUE, BMAPI will try to keep to part dimensions (at every bendline) constant whenever possible, when the user changes the part/bendline parameters dike, metal thickness, or bendline raidus, etc.) . Otherwise we don't care.
Default value is 0 - no need to keep dimensions constant .
*/ char bendline_dimensions_status ; public : /*
Constructors and destructors. In PART_NE .CPP,
I
BM_PART (void) ;
BM_PART (BM_PART *existing_part) ;
~BM PART(void) ;
// use this to erase the content of the part, the part will be empty.
// it will use topology: :erase_content () to destroy the topology and will then
// destroy all bodies in the part. void erase_content (void) ; void get_material_type (char *out_mat_type) ; void set_material_type(char *in_mat_type) ; void get_name (char *out_name) ; void set name (char +in name) ; void get_part_number(char +out_number) ; void set_part_number(char in_number) ;
// get number of faces, holes, bendlines inline long get_number_of_faces (void) const { return number_of_faces ; } inline long get_number_of_holes (void) const ( return number_of_holes ; } inline long get number_of_bendlines (void) const { return number_of_bendlines ; ""} APPENDIX K inline long get_number_of_formings (void) const { return number of formings ; }
// get pointers to lists of faces, holes and bendlines inline BM_FACE +get_face_list (void) const { return first_face inline BM_HOLE *get_hole_list (void) const { return first_hole inline BM_BENDLINE +get_bendline_list (void) const { return first_bendline ; } inline BM_FORMING +get_forming_list (void) const { return first_forming ; }
// To get the number of bend properties and the first property object on the list. inline BM_BEND_PROPERTY +get_list_of_bend_properties (void) const { return list_of_bend_properties ; } inline long get_number_of_bend_properties (void) const { return number_of_bend_properties ; }
// this function tries to find a good default base face. // it chooses a face that has the largest bbox. BM_FACE +get_default_base_face (void) ;
/ *
Functions to get and change the distance tolerance associated with the part.
*/ inline double get_distance_tolerance (void) const { return distance_tolerance ; } void set_distance_tolerance (double new_distance_tolerance) ;
/* *
To get the current metal thickness of this part.
*/ inline double get_metal_thickness (void) const { return metal_thickness ; }
/*
Changing thickness will cause a lot of changes in the part. Faces might need some trimming since changing thickness will most likely change bendlines. Also 2D->3D transformations of faces will most likely change. This will happen because the 3D shape of the bendline will change and since the flat represents neutral-line dimensions, the 3D dimensions of the part will most likely change. Bendlines are almost certain to change significantly. W3D of all bendlines has to be recomputed. Also, 2D->3D transformation might have to be recomputed. Note that the part itself does not move in space as the result of changing thickness. However, bendlines 2D->3D transformation will be marked as 'not-up-to-date' . One way APPENDIX K to update them is to pick any face as a base-face and re-fold the part (this will work only if the face picked has its 2D->3D transformation up to date) . The part will stay in the same place (since the base-face will stay in place) and bendlines will have their 2D->3D transformations updated.
Changing thickness is really tricky since most likely all bodies in the part will have 2D->3D transformations and 3D versions invalidated. The problem is that the user normally does not want to re-fold the part. Therefore we have to figure out how to get new valid 2D->3D transformations automatically. Note that this function does not do that. This is something that has to be done by some other function. Note that this function will not try to match faces-bendlines exactly. To accomplish that , call match_all_faces_adjacent_to_bendlines ( ... ) after this function. Even better yet, use set_metal_thickness_update_part ( ... ) which will set new thickness, and then match adjacent faces as well as compute new up-to-date 2D->3D transformations.
*/ void set_metal_thickness (double thickness) ; void set_metal_thickness_update_part (double thickness) ;
/*
This function will trim (if necessary) all faces so that in 3D space they will exactly touch bendlines adjacent to them.
This function is good to call after thickness has changed, or after bendline parameters have been changed.
*/ void match_all_faces_adjacent_to_bendlines (void) ;
/*
Add a 3D body (face, hole, forming or bendline) to the part.
Return FALSE if cannot add.
This function basically calls add_body0 member function of the topology.
*/ int add_3d_body(BM_3D_BODY *body) ;
// get part topology inline BM_TOPOLOGY *get_topology(void) const { return (BM_TOPOLOGY *) -topology ; }
/*
These function allow the user to query and specify whether part dimensions at bendline should be kept constant whenever possible, or not.
*/
// to get the current status
8 APPENDIX K inline int get_bendline_dimensions_status (void) const { return bendline_dimensions_status ; }
// to set the new status.
// for example, if we set it to TRUE, then from this point on, BMAPI
// will try to keep to current part dimensions constant. v o i d s e t _ b e n d l i n e _ d i m e n s i o n s _ s t a t u s ( i n t new_bendline_dimensions_status) ;
/*
Bend sequence related fundtions.
*/ void delete_bend_sequence (void) ; inline long get_bend_sequence_size (void) const { return bend_sequence_size ; }
// this function returns the number of bendlines copied into OUT array int get_bend_sequence (BM_BENDLINE +bendlines [] , long bendlines_array_length) ;
// this function sets a new bend sequence for this bendline int set_bend_sequence (BM_BENDLINE ++bendlines, long bendlines_array_length) ;
// this function checks is a bendline is in the current bend sequence of the part .
// if yes, it returns its index in the bend sequence (ie. the number of this bendline
// in the bend sequence order) . This index is from 0 through sequence_lenght - 1.
// if this bendline is not in the bend sequence, it returns -1. int is_bendline_in_bend_sequence (BM_BENDLINE +bendline) ;
// this function removes a bendline from the bend sequence.
// note that if the bendline is in a simultaneous bend property, it will replace the bendline
// with another bendline from the simultaneous bend property that is not already in the bend sequence. void remove_bendline_from_bend_sequence(BM_BENDLINE *bendline)
// this function deletes the current bend sequence (if one exists) and creates a default // bend sequence. void create_default_bend_sequence (void) ;
/*
This function will eliminate the flat version of all bendlines that do not contain holes.
This function can be useful after a part is unfolded. Normally a folded version of the part contains non-trivial bendlines (ie. inside radius and/or thickness not 0) .
When a part is unfolded, BMAPI transforms these bendlines into 55?
APPENDIX K a flat version exactly as they are.
For example, a 3D-version of a bendline with non-zero thickness or raidus has normally a bend arc drawn. This gets mapped onto flat version of the bendline, which means in the flat version of the part, there is a rectangle between the two faces corresponding to the bendline.
However, sometimes we don't want to see this rectangle.
This function processes only those bendlines that have a simple flat (ie. no holes in the flat) , and that are adjacent to exactly two faces.
This function trims all adjacenct faces so that they touch the bendline centerline and deletes all loops in the bendline flat.
Note that since this function is usually used right after UNFOLD. Once the flat is trimmed, it matches adjacent faces as well - this means that is computes and sets some special trimming values so that in the future when we fold the part we get a correct 3D-version where faces exactly meet bendlines . It does not change the bendline.
*/ void eliminate_simple_bendlines_in_flat_version_A(void) ;
/*
This function will scan all 3D-bodies in the part (except formings), and fix their flat versions. Basically it will call BM_2D_BODY: :fix_flat() function on every 3D_body (except formings) in the part. Note that it will only check the current flat version. It will return FAILURE when either some operation failed (ie. memory allocation) or when it discovered a problem that it cannot fix.
* / int fix flat (void)
/ *
This function checks that face normals are consistent with bendline definitions. For example, if facel has normal (0,0,1) and there is a 90 degree FRONT bend between facel and face2, then face2 normal must be (-1,0,0) . If there is a normal that is a reverse of what it should be, it fixes it. Otherwise when it finds a problem, it returns a FAILURE.
If an input face is given, it only checks the connected component centered at this face. Otherwise it checks the entire part . In that case the order in which it checks faces is the order of face indeces.
This function makes some necessary checks (for example, when a bendline is being bent, it has to have a bend op, a 3D-version
10 APPENDIX K
(although it can be empty) and a surface.
This function checks if 3D-versions of all faces and bendline are up to date. If any is not it will return FAILURE. It will just check if the current version is up to date, it will not compute new 3D-version if the current version is not up to date (because this function is usually used right before unfold - we don't want to compute anything new at this point) .
This function ignores holes and formings.
In 3D_FUNC.CPP. */ int fix_3D_face_normals (BM_FACE *given_base_face = NULL) ;
/*
This function will check 3D-bodies in the part and fix problems it finds. Note that it will only check current 3D-versions. Also, it will not invalidate anything.
Right now, it checks : that face normals are consistent with bendline definitions. For example, if facel has normal (0,0,1) and there is a 90 degree FRONT bend between facel and face2, then face2 normal must be (-1,0,0) .
It will return FAILURE when either some operation failed (ie. memory allocation) or when it discovered a problem that it cannot fix.
In 3D_FUNC.CPP.
*/ int fix_3D(void) ;
********** ********** ********** ********** **********
********** ********** ********** **********
This is a major high-level Bend Model function for part design and construction.
Its purpose is :
- to create bendlines between faces so that the part becomes connected (if possible) .
This function was created to facilitate part creation. Normally a third-party CAD program is used to draw a part. Since Bend Model does not have any control over the CAD system, for our purposes this drawing is just a set of edges. Therefore drawing has to be analyzed then in order to detect the structure of the part .
11 APPENDIX K
After that we can create faces and bendlines of the part .
However, the input drawing is often ambigious - faces and specially bendlines are not uniquely defined. Since this problem is common to many applications this function is part of the Bend Model. Moreover, implementing this function in Bend Model will simplify the face detection software that has to be part of the CAD system.
In this function we assume that edges of faces are sorted according to the left-hand side rule, in a way that is consistent with the plane normal (which defines the plane orientation) . Basically, this function assumes that every plane is correct by itself, when viewed in isolation. However, this function does not require that the orientation of adjacent planes be correct with respect to the bendlines between them.
This function probably does not work well if the part thickness is not zero.
This function can be used to generate bendlines for both 3D-version of the part and the flat version of the part. However, the part can have either the flat or 3D version of the part, but not both. In other words, either all 3D-version of 3D-bodies must be NULL (in which case we have a flat version) , or all flat versions must be NULL.
Implementation is in AUTO_BEND.CPP.
*/ int auto_bend(void) ;
/*
This function was designed to facilitate part creation from data send to Bend Model by a CAD system.
The problem is that the part is often constructed piece by piece, as information becomes available.
However, the problem is that as we construct bodies of the part, we don't know in advance whether the input data represents the FLAT or 3D version of the part.
Usually it is a 3D_version. Therefore by default we assume that it is the 3D version.
Later, once all 3D-bodies of the part have been constructed, we can check it this is true. If not, we have to move all 3D-version "into" flat versions.
This function was designed only for this specific purpose and should not be used for any other purpose. Misuse of this function can crash the system.
This function checks first if the FLAT version of a body is
12 APPENDIX K
NULL. If not, it does not move the 3D-version.
TODO : right now, it only moves faces. */ void BM_PART: :move_3D_to_flat (void) ;
/*
********** ********** ********** ********** ********** ********** ********** ********** **********
Bend Model can handle part manipulations in both directions :
- Given a 3D version of the part, find the 2D (flat) version of the part (ie. unfold) .
- Given a 2D (flat) version of the part, fold it given a set of bending parameters.
Since BMAPI will have two versions (2D and 3D) of the part most of the time, it is important to maintain their consistency.
BMAPI usually does not, for purposes of efficiency, explicitly compute 2D and 3D versions of the part, but instead computes them on demand - only when the user requests them. For most purposes, it is enough if we just know the transformations that produce of version of a body given another version of the body. Whenever the user manipulates the part, he is actually manipulating the transformations.
There is one difference between 2D->3D and 3D->2D transformations. 2D->3D transformation is usually specified by the user and he can do it in any way he wants (sometimes the result might not be valid for some reason, but we will ignore it here for now) . 3D->2D transformation corresponds to unfolding and there is only one way to do it - there is only one final flat version of the part given a fixed 3D-version.
Both fold and unfold use the bend information of the part to compute all 3D bodies separately according to their individual bending parameters. These transformation generally require that all bodies in the part have 'flat' or ' 3D-version' . That means, when you initially have a 3D version of the part, you have to unfold in before you can use 2D->3D transformations.
Unfolding produces 'flat' . Folding produces ' 3D-version' . Initially the user has to specify either the flat or the 3D-version.
********** ********** ********** ********** ********** ********** ********** ********** **********
13 APPENDIX K */
/*
This function will force BMAPI to compute the 3D version of the part (from flat) . Specifically, BMAPI will check every face-hole-bendline and whenever the 3D version is not up to date, it will compute an up-to-date 3D version from flat using the 2D->3D transformation. If the 2D->3D transformation is not up to date, it will try to compute a valid up to date 2D->3D transformation. Also, whenever a new 3D-version is computed for a bendline, it will first match adjacent bendlines.
*/ void bring_3D_up_to_date (void) ;
/ *
********** ********** ********** ********** ********** ********** ********** ********** **********
2D->3D transformation functions.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
/*
This function will reset all transformations to identity transformations.
It will also set 'bending_status' variable in every bendline to FALSE.
It will also mark all 3D versions of all faces as 'not-up-to-date' but won't recompute them.
Note that this function will reset only the 2D->3D transformation since 3D->2D transformation cannot be reset. */ void reset all transformations (void) ;
/ *
Reset part's 2D->3D transformations.
'body' is the face whose transformation will be an identity transformation. other bodies will have their transformations set according to the bend information with respect to this base body.
This function will update all transformation matrices.
Basically this function allows you to undo all rotations and translations you have done on the entire part.
*/ void reset_part_2Dto3D_transformations (BM_3D_BODY *base_body)
14 APPENDIX K
********** ********** ********** ********** ********** ********** ********** ********** **********
These function let the user to rotate or translate part. For example, when bending the user might want to move the part of flip it over.
These functions will apply to the entire part equally, ie. every face-hole-bendline changes in exactly the same way.
Note that these are 2D->3D transformations, ie. they change only the 3D version of the part, but they require that the flat version of the part be computed.
Basically the only thing these functions do is to change the 2D-3D transformation associated with every body and mark every body's 3D-version as 'not-up-to-date' .
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
/*
Rotate the entire part around the line by the angle (in radians) .
Positive direction is defined as clockwise when we look in the direction of the line.
*/ void rotate (BM_LINE const- line, double const angle) ;
/*
Translate the entire part by this vector.
*/ void translate (BM_VECTOR constSc translation_vector)
/*
Apply this transformation to the part. */ void transfor (BM_TRANSFORM const- transformation) ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
FOLD functions. In module FOLD.CPP.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
15 APPENDIX K
/ *
Compute 3D version of the part.
This function will compute the 3D version of the part with respect to this base body.
That is, 'base_body' will stay in place while the rest of the part moves .
Note that if you have done any rotations and/or translations with the entire part in the past, they will be in effect after this operation. Normally you want to set some bendline parameters and then call this function to update the part. This function will compute only the transformation matrices of those bodies that change (the minimum change) . 3D versions of every body will be computed on demand, ie. only when the user requests them.This function will use the 'bending_status' member variable of every bendline to determine whether a bendline should be bent.
Note that if the 2D->3D transformation of the base-body is not up to date, FOLD will reset it to an identity transformation.
*/ int fold(BM_3D_BODY *base_body) ;
/ *
This function does the same thing, except that it assumes that the 'bending_status' member variable of every bendline is FALSE (if it is not, it sets it to FALSE) and assumes that the list of bendlines to bend is in the array 'bendline_array' (the length of the array is 'number_of_bendlines' ) . At the end of this function, the 'bending_status' member variable of every bendline indicates whether the bendline was bent or not.
*/ int fold (BM_3D_B0DY *base_body, BM_BENDLINE *bendline_array [] , long number_of_bendlines) ;
/*
This function will fold first n bendline in the bend sequence of the part .
*/ int fold_sequence (BM_3D_BODY +base_body, int n) ;
/*
Given a 3D body that already has its 2D->3D transformation matrix computed, this function will compute a transformation matrix for a given bendline.
This function will assume a number of things (these are not checked) :
- this bendline is adjacent to the body
- this body already has an up-to-date transformation matrix
- this bendline has an up-to-date center_line_2D
16 APPENDIX K
Note that these two functions require that bendlines have 2D centerline. This also means that bendlines should have a flat. For performance reasons these functions do not check if bendlines have a flat, but instead assume that they do and reference it directly. This function is used by FOLD.
*/ int bend_bendline_wrt_3D_body(BM_3D_BODY +body /* finished body */,
BM_BENDLINE *current_bendline /* bendline whose transformation we are computing */,
BM TRANSFORM *tf /* start with this transformation /) ;
/*
The same, except the bendline is already finished and we are computing the 3D body.
This function is used by FOLD.
*/ intbend_3D_body_wrt_bendline (BM_BENDLINE *current_bendline /♦ finished bendline /,
BM_3D_BODY +body /* body whose transformation we are computing /,
BM_TRANSFORM +tf / start with this transformation */) ;
/*
********** ********** ********** ********** ********** ********** ********** ********** **********
UNFOLD functions. In module UNFOLD.CPP.
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
/*
This function will unfold the entire part.
It chooses a default base body for every connected component of the part. When the part is unfolded, this function will move it to the X-Y plane, such that the base-body overlaps the origin (0,0,0) .
This function will first compute 3D->2D transformation for every 3D-body, then compute Wflat for every 3D-body, then trim Wflat and finally compute flat.
This function chooses the face with the smallest id that has a non-NULL normal as the base-body.
If that is not possible, it chooses the first bendline that has an underlying surface for which a non-NULL normal can be computed as the base-body.
17 APPENDIX K
This function will use BM_PART: :unfold(BM_3D_BODY +base_body) to unfold all connected components of the part.
This function returns 1 iff everything was fine; 0 iff unfolding of some part of the part failed.
First this function will check that all face normals are correct with respect to current bendlines.
Note that this function will use the current 3D-version of every 3D-body. In order to unfold, all 3D-versions have to be up to date. This function will not check if they are up to date, it will actually mark all 3D-bodies as up to date. Also, it assumes that all bendlines have a valid 3D-centerline. Again, it will not check that, instead it will simply validate the current centerline.
*/ int unfold(void) ;
/*
This function will unfold only a connected component of the part, centered around the base-body.
This function is used by the BM_PART: :unfold(void) function that unfolds the entire part.
This function will compute new 3D->2D transformations for every 3D-body in the connected component, and will then use BM_3D_B0DY: :compute_flat_from_3D() function to compute a new flat version for every 3D-body.
If the base-body is a face and the input flag is set to TRUE, then thefirst thing this function does is to check that all face normals are correct with respect to current bendlines - but only in the connected component centered at this base-body(face) .
Note that this function will use the current 3D-version of every 3D-body.
Make sure that all 3D-versions are up to date before calling this function.
This function will actually mark all 3D-bodies it processes as up to date.
*/ int unfold(BM_3D_B0DY +base_body, int check_face_normals = 0)
;
/*
Given a 3D body that already has its 3D->2D transformation matrix computed, this function will compute a transformation matrix for a given bendline.
This function will assume a number of things (these are not checked) :
18 APPENDIX K
- this bendline is adjacent to the body
- this body already has an up-to-date transformation matrix
- this bendline has an up-to-date center_line_3D
Note that these two functions require that bendlines have a centerline. This also means that bendlines a non-NULL 3D-version. For performance reasons these functions do not check that, b t instead assume that they do and reference it directly.
This function is used by UNFOLD.
Note that this function is really an inverse of bend_bendline_wrt_3D_body(...) .
*/ int unfold_bendline_wrt_3D_body(BM_3D_BODY *body / finished body /,
BM_BENDLINE +current_bendline /* bendline whose transformation we are computing /,
BM_TRANSFORM +tf / start with this transformation +/) ;
/*
The same, except the bendline is already finished and we are computing the 3D body.
This function is used by UNFOLD.
Note that this function is really an inverse of bend_3D_body_wrt_bendline (...) .
*/ int unfold_3D_body wrt_bendline (BM_BENDLINE +current_bendline /♦ finished bendline */",
BM_3D_B0DY *body /* body whose transformation we are computing /,
BM_TRANSFORM +tf / start with this transformation ♦/) ;
/*
********** ********** ********** ********** **********
********** ********** ********** **********
This function returns a "paper model of this part". A paper model is a part that has thickness 0, bendline radius and bend deductions 0 as well. If required, this function will return a mapping from user-id's associated with bendlines into former values of 'inside radius' and 'bend deduction' .
********** ********** ********** ********** ********** ********** ********** ********** **********
*/
BM_PART +make_paper_model (double +*inside_radius /♦ OUT */, double ++bend deduction /♦ OUT ♦/) ;
19 APPENDIX K
/*
This function will save the current part in the given file in PGF format.
PGF format is used by CMU's BendCAD program.
Returns : TRUE iff everything is fine and the part is saved.
*/ int save_PGF_file(FILE *file) ; int save PGF file(char +filename) ;
/*
Load functions are in PART_LOAD_x.CPP. */ virtual int load(FILE *file) ; virtual int load(char filename / must not be NULL */) int BM PART Load(FILE *file, long version) ;
/*
Save functions are in PART_SAVE.CPP. */ virtual int save(FILE +file) ; virtual int save(char *filename / must not be NULL */)
} ;
#endif // BM PART HXX INCLUDED
20 APPENDIX L
/////////////////////////////////////////////////////////////////
// //
// Example of 3-D manipulation and navigation with dynamic // // calculation of the rotation axis. //
// //
// Copyright 1996 AmadaSoft America, Inc. // m // iiuuui mm miiimmumiiiuumuui muumum//
void CBendCADViewPart : :OnLButtonUp (UINT nFlags, CPoint point)
: :ReleaseCapture () ;
: :ClipCursor (NULL) ; // Release mouse, free cursor. m_lt_btn_up_point = point; double x_extent, y_extent; int add_hit_to_list = 0; int viewport [4] ;
BM_VECT0R offset;
BM_PART +part = GetDocument () ->get_part () ;
RwV3d vert; switch(ml_last_function_chosen) { case(ZOOM_WINDOW_MODE) : if (mi_dynamic_rot_center_on) {
// User has further zoomed in. compute_non_dyn_equivalent () ; } RwIdentityMatrix(md-dyn-rot-matrix) ; compute_zoom_region_translation ( ) ; x_extent = fabs ( (double) (m_lt_btn_down_point .x - m_lt_btn_up_point .x) ) *
2. O*md_current_view_vol [0] / (double) (m_old_rect .right) ; y_extent = fabs ( (double) (m_lt_btn_down_point .y - m_lt_btn_up_point .y) ) *
2. O*md_current_view_vol [1] / (double) (m_old_rect .bottom) ; set_new_view_volume (x_extent, y_extent) ; compute_part_bbox(part, mi_show_3d, md_rot_matrix, m_part_centroid, md_part_bbox_size, -offset) ; mi_bbox_is_up_to_date = 0; // Even though bbox computed, we mark as not up to date so that zoom-all
DrawPart (m_hdc) ; // will work correctly.
// Now turn on dynamic rotation center if need be. if ( (md_part_bbox_size [0] > APPENDIX L
2.2*md_current_view_vol [0] ) ] | // User has zoomed in so that not all
( m d _ p a r t _ b b o x _ s i z e [ l ] >
2.2*md_current_view_vol [1] ) ) { // of the part is in view volume . if ( ! md_dyn_rot_matrix) md_dyn_rot_matrix = RwCreateMatrix() ; if (mi show_solid) {
7/ Pick the center of the screen to find point on clump to rotate around. i f ( R w P i c k S c e n e ( m _ s c e n e , m_old_rect . right /2 , m_old_rect .bottom/2 , m_camera, _m_pick) ) { if (m_pick. type == rwNAPICKOBJECT) { // No clump was picked. m_dynamic_rot_center = BM_POINT(0.0, 0.0, 0.0) ;
} else if (m_pick. type == rwPICKCLUMP) { // Some clump was picked; process it. v e r t = m_pick . obj ect . clump . wcpoint ,- m_dynamic_rot_center = BM_POINT (vert .x, vert.y, vert.z)
}
}
} else { m_dynamic_rot_center = BM_P0INT (0.0, 0.0,
0.0) ;
} mi_dynamic_rot_center_on = 1;
} else { compute_non_dyn_equivalent () ; i f ( m d _ d y n _ r o t _ m a t r i x ) RwDestroyMatrix(md_dyn_rot_matrix) ,- md_dyn_rot_matrix = NULL; mi dynamic rot center on = 0;
} " " " break; case(SELECT_OBJECTS_MODE) : if (nFlags Sc MK_CONTROL) add_hit_to_list = 1; if ( ! mi_show_solid) { // Wireframe being displayed, which means OpenGL picking. glGetIntegerv(GL_VIEWPORT, viewport) ; glMatrixMode (GL_PROJECTION) ; glPushMatrixO ; glLoadldentity0 ; APPENDIX L gluPickMatrix ( ( doubl e ) point . x , (double) (m_old_rect. bottom - point. y) , 3.0, 3.0, viewport) ; glOrtho (- md_current_view_vol [0] , md_current_view_vol [0] ,
- md_current_view_vol [1] , md_current_view_vol [1] ,
- md_current_view_vol [2] , md_current_view_vol [2] ) ; glMatrixMode (GL_MODELVIEW) ;
DrawPart (m_hdc) ; //
Draw the part in selection mode. glMatrixMode (GL_PROJECTION) ; glPopMatrix() ; glMatrixMode (GL_MODELVIEW) ; process_hits_record(add_hit_to_list) ; ml_last_function_chosen = NO_FUNCTION_MODE; DrawPart (m_hdc) ; reset_selection_buffer() ; else { // Solid being shown, so RenderWare picking. if (RwPickScene (m_scene, point.x, point.y, m_camera, _m_pick) ) process_hits_record(add_hit_to_list) ; ml_last_function_chosen = NO_FUNCTION_MODE; DrawPart (m hdc) ;
} break; case(ZOOM_IN_OUT_MODE) : compute_part_bbox(part, mi_show_3d, md_rot_matrix, m_part_centroid, md_part_bbox_size, -offset) ; mi_bbox_is_up_to_date = 0; if (mi dynamic_rot_center_on) {
7/ User has further zoomed in. compute_non_dyn_equivalent () ; RwIdentityMatrix(md_dyn_rot_matrix) ;
// Now turn on dynamic rotation center if need be. i f ( ( m d p a r t b b o x _ s i z e [ 0 ] >
2.2*md_current_view_vol [0] ) | //"User has zoomed in so that not all
( m d _ p a r t b b o x _ s i z e [ l ] >
2.2+md_current_view_vol [1] ) ) { ll oi the part is in view volume . mi_bbox_is_up_to_date = 0; // Even though bbox computed, we mark as not up to date so that zoom-all if(! md_dyn_rot_matrix) md_dyn_rot_matrix = RwCreateMatrixO ; // will work APPENDIX L correctly. if (mi_show_solid) {
// Pick the center of the screen to find point on clump to rotate around. i f ( R w P i c k S c e n e ( m_ s c e n e , m_old_rect . right /2 , m_old_rect .bottom/2, m_camera, _m_pick) ) { if (m_pick.type == rwNAPICKOBJECT) { // No clump was picked. m_dynamic_rot_center = BM_POINT(0.0, 0.0, 0.0) ;
} else if (m_pick.type == rwPICKCLUMP) { // Some clump was picked; process it. v e r t m_pick.object .clump.wcpoint; m_dynamic_rot_center = BM_P0INT(vert .x, vert.y, vert.z)
» > else { m_dynamic_rot_center = BM_POINT (0.0, 0.0,
0.0)
} mi dynamic rot center on = 1;
} else { if (mi_dynamic_rot_center_on) { compute_non_dyn_equivalent () ; i f ( m d _ d y n _ r o t _ m a t r i x ) RwDestroyMatrix(md_dyn_rot_matrix) ; md_dyn_rot_matrix = NULL; mi dynamic rot center on = 0;
break; default: break;
}; ml_last_function_chosen = NO_FUNCTION_MODE; CBendCADView: :OnLButtonUp (nFlags, point) ;

Claims

5 «WHAT IS CLAIMED:
1. A system for developing a bend model of a part to be produced in an
intelligent production facility, said part including a plurality of faces and at least one
bendline, said system comprising:
a receiving system for receiving initial part information relating to said part, said
initial part information including data relating to a representation of said part within a
first predetermined coordinate space;
a face detecting system for detecting, within said first predetermined coordinate
space, said faces of said part based on said initial part information;
a bendline identification system for identifying at least one bendline of said part
based on said faces detected by said face detecting system; and
a system for generating additional part information, relating to said part and
including data relating to a representation of said part within a second predetermined
coordinate space, by performing a predetermined operation on each of said faces detected by said face detecting system, said operation being performed based upon at least said
initial part information and at least one bendline identified by said bendline identification
system.
2. A system according to claim 1, wherein said first predetermined
coordinate space comprises a 2-D coordinate space and said second predetermined
coordinate space comprises a 3-D coordinate space, said predetermined operation
comprising a folding operation performed on said faces detected by said face detecting system.
3. A system according to claim 2, said folding operation including rotating _- <"v ι_ / 7473
5* 1
and translating each of said faces detected by said face detecting system relative to at
least one bendline identified by said bendline identification system.
4. A system according to claim 2, wherein said initial part information
further comprises a bend angle amount relating to at least one bendline of said part, said
folding operation being performed based on said bend angle amount.
5. A system according to claim 4, wherein said folding operation comprises
rotating and translating each of said faces around at least one bendline of said part based
on said bend angle amount.
6. A system according to claim 1, wherein said first predetermined
coordinate space comprises a 3-D coordinate space and said second predetermined
coordinate space comprises a 2-D coordinate space, said predetermined operation
comprising an unfolding operation performed on said faces detected by said face
detecting system.
7. A system according to claim 6, said unfolding operation including rotating
and translating each of said faces detected by said face detecting system relative to at
least one bendline identified by said bendline identification system.
8. A system according to claim 6, wherein said initial part information
further comprises a bend angle amount relating to at least one bendline of said part, said
unfolding operation being performed based on said bend angle amount.
9. A system according to claim 8, wherein said unfolding operation
comprises rotating and translating each of said faces around at least one bendline of said
part based on said bend angle amount.
10. A system according to claim 1, wherein said data relating to a » «* -_,
representation of said part within a first predetermined coordinate space comprises
coordinate data.
11. A system according to claim 1, wherein said data relating to a
representation of said part within a first predetermined coordinate space comprises vector
data.
12. A system according to claim 1 , wherein said part comprises a sheet metal
part.
13. A system according to claim 1 , wherein said faces comprise base surfaces
of said part and folded surfaces of said part.
14. A system according to claim 1 , further comprising a system for detecting additional features of said part, said predetermined operation being performed on said
additional features of said part.
15. A system according to claim 14, said additional features comprising holes,
openings and special formings of said part.
16. A system according to claim 1, wherein said initial part information
comprises data relating to a representation of said part in a 3-D coordinate space, said
data including thickness data of said part in said 3-D coordinate space.
17. A system according to claim 16, further comprising a system for
eliminating said thickness data to provide modified part data relating to a representation
of said part in said 3-D coordinate space with no thickness.
18. A system according to claim 17, wherein said face detecting system detects said faces of said part based on said modified part data and said representation of
said part in said 3-D coordinate space with no thickness.
19. A system according to claim 18, wherein said second predetermined
coordinate space comprises a 2-D coordinate space, said predetermined operation
comprising an unfolding operation performed on said faces detected by said face
detecting system.
20. A system according to claim 19, said unfolding operation including
rotating and translating each of said faces detected by said face detecting system relative
to at least one bendline identified by said bendline identification system.
21. A system according to claim 1 , further comprising an auto-trimming and
cleanup system for performing an auto-trimming and cleanup operation on said data
relating to said initial part information to prepare said data for said face detecting system
and said bendline identification system.
22. A system according to claim 21 , wherein said data comprises part entity
data representing, at least, line entities and bendline entities of said part, said auto-
trimming and cleanup system comprising a system for detecting intersection points of
said entities and for selectively breaking said entities at detected intersection points, and
a system for assigning the resultant broken entities to have a common endpoint based on
said detected intersection points.
23. A system according to claim 21 , wherein said data comprises part entity
data representing, at least, line entities of said part, said auto-trimming and cleanup
system comprising a system for detecting open intersection areas between adjacent
entities and for selectively connecting said adjacent entities by assigning a common
endpoint to said adjacent entities.
24. A system according to claim 23, wherein an open intersection area is detected, by said system for detecting open intersection areas, if the endpoints of said
adjacent entities are within a predetermined distance from one another.
25. A system according to claim 1 , wherein said data relating to said initial
part information comprises part entity data representing, at least, line entities of said part,
said face detecting system performing a loop and entity analysis of said part based on
said part entity data to detect said faces of said part.
26. A system according to claim 25, wherein said loop and entity analysis is
initially performed on an outside boundary of said part and then performed on inner
boundaries and areas of said part.
27. A system according to claim 26, wherein said face detecting system
generates an initial linked list of entities when performing said loop and entity analysis
on the outside boundary of said part, said initial linked list of entities defining an outward
loop and boundary of said part.
28. A system according to claim 27, wherein said face detecting system
further generates an additional linked list of entities when performing said loop and entity
analysis on the inside boundaries and areas of said part, said additional linked list of
entities defining inner loops and boundaries of said part.
29. A system according to claim 28, wherein said face detecting system
further comprises a system for generating a loop tree based on said outward loop defined
by said initial linked list of entities and said inner loops defined by said additional linked
list of entities.
30. A system according to claim 29, wherein said face detecting system
detects said faces of said part based on said loop tree and the sequence of boundaries 7473
defined by said initial linked list entities and said additional linked list of entities. »
31. A system according to claim 28, wherein said bendline identification
system comprises a system for analyzing said initial linked list of entities and said
additional linked list of entities
to determine common line entities between said faces detected by said face detecting
system.
32. A system according to claim 31 , said at least one bendline being identified
based on the detection of one of said faces having only one common line entity with another one of said faces.
33. A system according to claim 32, wherein said at least one bendline is
identified and defined at said one common line entity detected between said faces.
34. A system according to claim 32, wherein said bendline identification
system applies predetermined heuristics to identify bendlines of said part when said
system for determining common line entities detects that there are more than one
common line entity between said faces.
35. A system according to claim 34, wherein said heuristics comprise
identifying bendlines of said part such that a minimum number of total bendlines are
identified for said part.
36. A system according to claim 34, wherein said heuristics comprise
identifying bendlines of said part, when one of said faces have more than one common
line entity with another one of said faces, based on the common line entity that has the
longest length.
37. A system according to claim 1, wherein said bendline identification system comprises a system for detecting common edges between said faces detected by
said face detecting system, said at least one bendline being identified based on the
detection of one of said faces having only one common edge with another one of said
faces.
38. A system according to claim 37, wherein said at least one bendline is
identified and defined at said one common edge detected
between said faces.
39. A system according to claim 37, wherein said bendline identification
system applies predetermined heuristics to identify bendlines of said part when said
system for detecting common edges detects that there are more than one common edge
between said faces.
40. A system according to claim 39, wherein said heuristics comprise
identifying bendlines of said part such that a minimum number of total bendlines are
identified for said part.
41. A system according to claim 39, wherein said heuristics comprise
identifying bendlines of said part, when one of said faces have more than one common
edge with another one of said faces, based on the common edge that has the longest length.
42. A system according to claim 1 , further comprising a system for receiving
a deduction amount related to said part and a system for compensating for bend
deduction, when performing said predetermined operation on said faces, based on said deduction amount.
43. A system according to claim 42, wherein said predetermined operation comprises a folding operation performed on said faces detected by said face detecting
system, said system for compensating for bend deduction increasing a dimensional length
of said faces by one half of said deduction amount on each side of said bendline of said
part when performing said folding operation.
44. A system according to claim 42, wherein said predetermined operation
comprises an unfolding operation performed on said faces detected by said face detecting
system, said system for compensating for bend deduction decreasing a dimensional
length of said faces by one half of said deduction amount on each side of said bendline of said part when performing said unfolding operation.
45. A method for developing a bend model of a part to be produced in an
intelligent production facility, said part including a plurality of faces and at least one
bendline, said method comprising the steps of:
receiving initial part information relating to said part, said initial part information
including data relating to a representation of said part within a first predetermined
coordinate space; detecting, within said first predetermined coordinate space, said faces of said part
based on said initial part information;
identifying at least one bendline of said part based on said faces detected by said
detecting; and generating additional part information, including data relating to a representation
of said part within a second predetermined coordinate space, by performing a
predetermined operation on each of said faces detected by said detecting, said operation
being performed based upon said initial part information and at least one bendline 5* l
identified by said identifying.
46. A method according to claim 45, wherein said first predetermined
coordinate space comprises a 2-D coordinate space and said second predetermined
coordinate space comprises a 3-D coordinate space, said method further comprising
performing a folding operation on said faces detected by said detecting.
47. A method according to claim 46, said folding operation including rotating
and translating each of said faces relative to at least one bendline identified by said
identifying.
48. A method according to claim 46, wherein said initial part information
further comprises a bend angle amount relating to at least one bendline of said part, said
folding operation being performed based on said bend angle amount.
49. A method according to claim 48, wherein said folding operation comprises
rotating and translating each of said faces around at least one bendline of said part based
on said bend angle amount.
50. A method according to claim 45, wherein said first predetermined
coordinate space comprises a 3-D coordinate space and said second predetermined
coordinate space comprises a 2-D coordinate space, said method further comprising
performing an unfolding operation on said faces detected by said detecting.
51. A method according to claim 50, said unfolding operation including
rotating and translating each of said faces relative to at least one bendline identified by
said identifying.
52. A method according to claim 50, wherein said initial part information
further comprises a bend angle amount relating to at least one bendline of said part, said unfolding operation being performed based on said bend angle amount.
53. A method according to claim 52, wherein said unfolding operation
comprises rotating and translating each of said faces around at least one bendline of said
part based on said bend angle amount.
54. A method according to claim 45, further comprising detecting additional
features of said part, said predetermined operation being performed on said additional
features of said part.
55. A method according to claim 54, said additional features comprising
holes, openings and special formings of said part.
56. A method according to claim 45, wherein said initial part information
comprises data relating to a representation of said part in a 3-D coordinate space, said
data including thickness data of said part in said 3-D coordinate space.
57. A method according to claim 56, further comprising eliminating said
thickness data to provide modified part data relating to a representation of said part in
said 3-D coordinate space with no thickness.
58. A method according to claim 57, wherein said detecting said faces of said
part is adapted to be performed based on said modified part data and said representation
of said part in said 3-D coordinate space with no thickness.
59. A method according to claim 58, wherein said second predetermined
coordinate space comprises a 2-D coordinate space, said method further comprising
performing an unfolding operation on said faces detected by said detecting.
60. A method according to claim 45, further comprising performing an auto-
trimming and cleanup operation on said data of said initial part information before 5*3
detecting said faces and identifying said at least one bendline.
61. A method according to claim 45, wherein said data of said initial part
information comprises part entity data representing, at least, line entities of said part, said
detecting of said faces comprising performing a loop and entity analysis of said part
based on said part entity data to detect said faces of said part.
62. A method according to claim 61 , wherein said loop and entity analysis is
initially performed on an outside boundary of said part and then performed on inner
boundaries and areas of said part.
63. A method according to claim 45, wherein said identifying said at least one
bendline comprises detecting common edges between said faces detected by said
detecting, said at least one bendline
being identified based on the detection of one of said faces having only one common
edge with another one of said faces.
64. A method according to claim 63, wherein said identifying of said at least one bendline further comprises applying predetermined heuristics to identify bendlines
of said part when more than one common edge between said faces is detected.
65. A method according to claim 64, wherein said heuristics comprise
identifying bendlines of said part such that a minimum number of total bendlines are
identified for said part.
66. A method according to claim 64, wherein said heuristics comprise
identifying bendlines of said part, when one of said faces have more than one common edge with another one of said faces, based on the common edge that has the longest length.
67. A method according to claim 45, further comprising receiving a deduction
amount related to said part and compensating for bend deduction, when performing said
predetermined operation on said faces, based on said deduction amount.
68. A method according to claim 67, further comprising performing a folding
operation on said faces, said compensating for bend deduction comprising increasing a
dimensional length of said faces by one half of said deduction amount on each side of
said bendline of said part when said folding operation is performed.
69. A method according to claim 67, further comprising performing an unfolding operation on said faces, said compensating for bend deduction comprising
decreasing a dimensional length of said faces by one half of said deduction amount on
each side of said bendline of said part when said unfolding operation is performed.
70. A system for developing a bend model of a part to be produced in a
production facility, said part including a plurality of faces and at least one bendline, said
system comprising:
means for receiving initial part information relating to said part, said initial part
information including data relating to a representation of said part within a first
predetermined coordinate space;
means for detecting, within said first predetermined coordinate space, said faces
of said part based on said initial part information;
means for identifying at least one bendline of said part based on said faces
detected by said face detecting means; and means for generating additional part information, including data relating to a representation of said part within a second predetermined coordinate space, by
performing a predetermined operation on said faces detected by said detecting means,
said predetermined operation being performed based on, at least in part, said bendline
identified by said bendline determining means.
71. A system according to claim 70, wherein said first predetermined
coordinate space comprises a 2-D coordinate space and said second predetermined
coordinate space comprises a 3-D coordinate space, said predetermined operation
comprising a folding operation performed on said faces detected by said face detecting
means.
72. A system according to claim 71 , said folding operation including rotating
and translating each of said faces detected by said face detecting means relative to at least
one bendline identified by said bendline identification means.
73. A system according to claim 71, wherein said initial part information
further comprises a bend angle amount relating to at least one bendline of said part, said
folding operation being performed based on said bend angle amount.
74. A system according to claim 70, wherein said first predetermined
coordinate space comprises a 3-D coordinate space and said second predetermined
coordinate space comprises a 2-D coordinate space, said predetermined operation
comprising an unfolding operation performed on said faces detected by said face
detecting means.
75. A system according to claim 74, said unfolding operation including
rotating and translating each of said faces detected by said face detecting means relative to at least one bendline identified by said bendline identification means.
76. A system according to claim 74, wherein said initial part information
further comprises a bend angle amount relating to at least one bendline of said part, said
unfolding operation being performed based on said bend angle amount.
77. A system according to claim 70, further comprising means for detecting
additional features of said part, said predetermined operation being performed on said
additional features of said part.
78. A system according to claim 77, said additional features comprising holes,
openings and special formings of said part.
79. A system according to claim 70, wherein said initial part information comprises data relating to a representation of said part in a 3-D coordinate space, said
data including thickness data of said part in said 3-D coordinate space.
80. A system according to claim 79, further comprising means for eliminating
said thickness data to provide modified part data relating to a representation of said part
in said 3-D coordinate space with no thickness.
81. A system according to claim 80, wherein said face detecting means detects
said faces of said part based on said modified part data and said representation of said
part in said 3-D coordinate space with no thickness.
82. A system according to claim 81, wherein said second predetermined
coordinate space comprises a 2-D coordinate space, said predetermined operation
comprising an unfolding operation performed on said faces detected by said face
detecting means.
83. A system according to claim 70, further comprising auto-trimming and
cleanup means for performing an auto-trimming and cleanup operation on said data 5
relating to said initial part information to prepare said data for said face detecting means
and said bendline identification means.
84. A system according to claim 83, wherein said data comprises part entity
data representing, at least, line entities and bendline entities of said part, said auto-
trimming and cleanup means comprising means for detecting intersection points of said
entities and for selectively breaking said entities at detected intersection points, and
means for assigning the resultant broken entities to have a common endpoint based on
said detected intersection points.
85. A system according to claim 83, wherein said data comprises part entity
data representing, at least, line entities of said part, said auto-trimming and cleanup
means comprising means for detecting open intersection areas between adjacent entities and for selectively connecting said adjacent entities by assigning a common endpoint to
said adjacent entities.
86. A system according to claim 85, wherein an open intersection area is
detected, by said means for detecting open intersection areas, if the endpoints of said
adjacent entities are within a predetermined distance from one another.
87. A system according to claim 70, wherein said data relating to said initial
part information comprises part entity data representing, at least, line entities of said part,
said face detecting means performing a loop and entity analysis of said part based on said
part entity data to detect said faces of said part.
88. A system according to claim 87, wherein said loop and entity analysis is
initially performed on an outside boundary of said part and then performed on inner boundaries and areas of said part. 5 P
89. A system according to claim 88, wherein said face detecting means
generates an initial linked list of entities when performing said loop and entity analysis
on the outside boundary of said part, said initial linked list of entities defining an outward
loop and boundary of said part.
90. A system accordingto claim 89, wherein said face detecting means further
generates an additional linked list of entities when performing said loop and entity
analysis on the inside boundaries and areas of said part, said additional linked list of
entities defining inner loops and boundaries of said part.
91. A system according to claim 90, wherein said face detecting means further
comprises means for generating a loop tree based on said outward loop defined by said
initial linked list of entities and said inner loops defined by said additional linked list of
entities.
92. A system according to claim 91 , wherein said face detecting means detects
said faces of said part based on said loop tree and the sequence of boundaries defined by
said initial linked list entities and said additional linked list of entities.
93. A system according to claim 70, wherein said bendline identification
means comprises means for detecting common edges between said faces detected by said
face detecting means, said at least one bendline being identified based on the detection
of one of said faces having only one common edge with another one of said faces.
94. A system according to claim 93, wherein said bendline identification
means applies predetermined heuristics to identify bendlines of said part when said
means for detecting common edges detects that there are more than one common edge
between said faces.
95. A system according to claim 94, wherein said heuristics comprise
identifying bendlines of said part such that a minimum number of total bendlines are
identified for said part.
96. A system according to claim 94, wherein said heuristics comprise
identifying bendlines of said part, when one of said faces have more than one common
edge with another one of said faces, based on the common edge that has the longest
length.
97. A system according to claim 70, further comprising means for receiving
a deduction amount related to said part and means for compensating for bend deduction,
when performing said predetermined operation on said faces, based on said deduction
amount.
98. A system according to claim 97, wherein said predetermined operation
comprises a folding operation performed on said faces detected by said face detecting
means, said means for compensating for bend deduction increasing a dimensional length
of
said faces by one half of said deduction amount on each side of said bendline of said part
when performing said folding operation.
99. A system according to claim 97, wherein said predetermined operation
comprises an unfolding operation performed on said faces detected by said face detecting
means, said means for compensating for bend deduction decreasing a dimensional length
of said faces by one half of said deduction amount on each side of said bendline of said
part when performing said unfolding operation.
100. A system for developing a bend model of a part to be produced in an 5 SO
intelligent production facility, said system comprising:
a receiving system for receiving initial part information relating to said part, said
initial part information comprising respective representations of a plurality of views said
part in 2-D coordinate space, each of said representations including part thickness
representations of said part, said initial part information further comprising extraneous information;
a cleanup operation system that performs a 2-D cleanup operation on said initial
part information to eliminate said extraneous information and to identify each of said
representations;
a part thickness elimination system for selectively eliminating said part thickness
representations in each of said identified representations to provide modified
representations of said views of said part in 2-D coordinate space with no thickness; and
a system for developing a representation of said part in 3-D coordinate space
based on said modified representations of said part in 2-D coordinate space with no
thickness.
101. A system according to claim 100, wherein said initial part information
comprises part entity data representing, at least, line entities of said part, said cleanup
operation system comprising a break and trimming system for detecting intersection
points of said entities and for selectively breaking said entities at detected intersection
points, said break and trimming system assigning the resultant broken entities to have a
common endpoint based on said detected intersection points.
102. A system according to claim 101, said break and trimming system further
comprising a system for detecting open intersection areas between adjacent entities and for selectively connecting said adjacent entities by assigning a common endpoint to said
adjacent entities.
103. A system according to claim 102, wherein an open intersection area is
detected, by said system for detecting open intersection areas, if the endpoints of said
adjacent entities are within a predetermined distance from one another.
104. A system according to claim 100, wherein said cleanup operation system
comprises a system for developing a connectivity graph structure based on said initial
part information, said cleanup operation system eliminating said extraneous information
based on said connectivity graph structure.
105. A system according to claim 104, wherein said extraneous information
comprises unconnected line entities, said unconnected line entities relating to, at least,
dimension lines.
106. A system according to claim 100, wherein said initial part information
comprises type field dala for identifying part entity data and extraneous information
relating to text, said cleanup operation system eliminating said extraneous information
relating to text based on said type field data.
107. A system according to claim 100, wherein said plurality of views comprise
a top view, a front view, and a right side view of said part in 2-D coordinate space.
108. A system according to claim 107, wherein said cleanup operation system
comprises a system for detecting, based on said initial part information, said
representations of said top view, said front view, and said right side view of said part.
109. A system according to claim 100, wherein said part comprises a sheet
metal part.
1 10. A system according to claim 100, wherein said part thickness elimination
system comprises a system for prompting a user to identify said part thickness
representations to be eliminated in each of said plurality of views and to identify a
dimension of said part to be retained in each of said plurality of views.
1 1 1. A system according to claim 1 10, wherein said dimension of said part
comprises one of an outside dimension or an inside dimension of said part.
112. A system according to claim 100, wherein said developing system
comprises a system for performing a projection operation to develop said representation
of said part in 3-D coordinate space based on said modified representations of said part
in 2-D coordinate space.
113. A system according to claim 112, wherein said projection operation
comprises detecting the relative depths of each of said plurality of views and projecting
each of said plurality of views into 3-D coordinate space.
114. A method for developing a bend model of a part to be produced in an
intelligent production facility, said system comprising the steps of:
receiving initial part information relating to said part, said initial part information
comprising respective representations of a plurality of views said part in 2-D coordinate
space, each of said representations including part thickness representations of said part;
performing a 2-D cleanup operation on said initial part information to eliminate
extraneous information and to identify each of said representations;
selectively eliminating said part thickness representations in each of said
identified representations to provide modified representations of said views of said part
in 2-D coordinate space with no thickness; and developing a representation of said part in 3-D coordinate space based on said
modified representations of said part in 2-D coordinate space with no thickness.
115. A method according to claim 114, wherein said initial part information
comprises part entity data representing, at least, line entities of said part, said performing
comprising detecting intersection points of said entities and selectively breaking said
entities at detected intersection points, said resultant broken entities being assigned to
have a common endpoint based on said detected intersection points.
116. A method according to claim 114, said performing comprising detecting
open intersection areas between adjacent entities and selectively connecting said adjacent
entities by assigning a common endpoint to said adjacent entities.
1 17. A method according to claim 1 16, wherein an open intersection area is
detected, by said step of detecting open intersection areas, if the endpoints of said
adjacent entities are within a predetermined distance from one another.
118. A method according to claim 1 14, said performing comprising developing
a connectivity graph structure based on said initial part information and eliminating said
extraneous information based on said connectivity graph structure.
119. A method according to claim 1 18, wherein said extraneous information
comprises unconnected line entities, said unconnected line entities relating to, at least,
dimension lines.
120. A method according to claim 114, wherein said initial part information
comprises type field data for identifying part entity data and extraneous information
relating to text, said performing eliminating said extraneous information relating to text
based on said type field data.
121. A method according to claim 1 14, wherein said plurality of views comprise
a top view, a front view, and a right side view of said part in 2-D coordinate space.
122. A method according to claim 121, wherein said performing comprises
detecting, based on said initial part information, said representations of said top view,
said front view, and said right side view of said part.
123. A method according to claim 1 14, wherein said part comprises a sheet metal
part.
124. A method according to claim 1 14, wherein said selectively eliminating said
part thickness comprises prompting a user to identify said part thickness representations
to be eliminated in each of said plurality of views and to identify a dimension of said part
to be retained in each of said plurality of views.
125. A method according to claim 124, wherein said dimension of said part
comprises one of an outside dimension or an inside dimension of said part.
126. A method according to claim 1 14, wherein said developing comprises
performing a projection operation to develop said representation of said part in 3-D
coordinate space based on said modified representations of said part in 2-D coordinate
space.
127. A method according to claim 126, wherein said projection operation
comprises detecting the relative depths of each of said plurality of views and projecting
each of said plurality of views into 3-D coordinate space.
128. A system for developing a bend model of a part to be produced in an
intelligent production facility, said system comprising: a receiving system for receiving initial part information relating to said part, said initial part information comprising respective representations of a plurality of views said
part in 2-D coordinate space, each of said representations including part thickness
representations of said part, said initial part information further comprising extraneous
information; a cleanup operation system that performs a 2-D cleanup operation on said initial
part information to eliminate said extraneous information and to identify each of said
representations; and
a system for developing a representation of said part in 3-D coordinate space
based on said identified representations of said part in 2-D coordinate space.
129. A system according to claim 128, wherein said initial part information
comprises part entity data representing, at least, line entities of said part, said cleanup
operation system comprising a break and trimming system for detecting intersection
points of said entities and for selectively breaking said entities at detected intersection
points, said break and trimming system assigning the resultant broken entities to have a
common endpoint based on said detected intersection points.
130. A system according to claim 129, said break and trimming system further
comprising a system for detecting open intersection areas between adjacent entities and
for selectively connecting said adjacent entities by assigning a common endpoint to said
adjacent entities.
131. A system according to claim 130, wherein an open intersection area is
detected, by said system for detecting open intersection areas, if the endpoints of said
adjacent entities are within a predetermined distance from one another.
132. A system according to claim 128, wherein said plurality of views comprise a top view, a front view, and a right side view of said part in 2-D coordinate space.
133. A system according to claim 132, wherein said cleanup operation system
comprises a system for detecting, based on said initial part information, said
representations of said top view, said front view, and said right side view of said part.
134. A system according to claim 128, wherein said part comprises a sheet metal
part.
135. A system according to claim 128, further comprising
a part thickness elimination system for selectively eliminating said part thickness
representations in each of said identified representations to provide modified
representations of said views of said part in 2-D coordinate space with no thickness, said developing system being adapted to develop said representation of said part in 3-D
coordinate space based on each of said identified representations of said part.
136. A system according to claim 135, wherein said part thickness elimination
system comprises a system for prompting a user to identify said part thickness
representations to be eliminated in each of said plurality of views and to identify a
dimension of said part to be retained in each of said plurality of views.
137. A system according to claim 128, wherein said developing system
comprises a system for performing a projection operation to develop said representation
of said part in 3-D coordinate space based on said identified representations of said part
in 2-D coordinate space.
138. A system according to claim 137, wherein said projection operation comprises detecting the relative depths of each of said plurality of views and projecting
each of said plurality of views into 3-D coordinate space.
139. A system according to claim 128, further comprising a system for
performing a 3-D clean-up operation on said representafionof said part in 3-D coordinate
space to further clean-up and eliminate extraneous information in said representation of
said part.
140. A system according to claim 139, wherein said 3-D clean-up operation
includes a process for identifying and eliminating one sided open lines that are present
in said representation of said part in 3-D coordinate space.
141. A system according to claim 139, wherein said 3-D clean-up operation
includes a process for identifying and cleaning each bendline that is present in said
representation of said part in 3-D coordinate space.
142. A system according to claim 139, wherein said 3-D clean-up operation
includes a process for trimming each face that is present in said representation of said part
in 3-D coordinate space.
143. A system for developing a bend model of a part to be produced in an intelligent production facility, said system comprising:
a receiving system for receiving initial part information relating to said part, said
initial part information comprising respective representations of a plurality of views said
part in 2-D coordinate space, each of said representations including part thickness
representations of said part;
a part thickness elimination system for selectively eliminating said part thickness
representations in each of said representations to provide modified representations of said
views of said part in 2-D coordinate space with no thickness; and
a system for developing a representation of said part in 3-D coordinate space based on said modified representations of said part in 2-D coordinate space with no
thickness.
144. A system according to claim 143, wherein said initial part information
further comprises extraneous information, said system further comprising a cleanup
operation system that performs a 2-D cleanup operation on said initial part information
to eliminate said extraneous information and to identify each of said representations.
145. A system according to claim 144, wherein said initial part information
further comprises part entity data representing, at least, line entities of said part, said
cleanup operation system comprising a break and trimming system for detecting
intersection points of said entities and for selectively breaking said entities at detected
intersection points, said break and trimming system assigning the resultant broken
entities to have a common endpoint based on said detected intersection points.
146. A system according to claim 143, wherein said developing system
comprises a system for performing a projection operation to develop said representation
of said part in 3-D coordinate space based on said modified representations of said part
in 2-D coordinate space.
147. A system according to claim 146, wherein said projection operation
comprises detecting the relative depths of each of said plurality of views and projecting
each of said plurality of views into 3-D coordinate space.
148. A system according to claim 143, wherein said part thickness elimination
system comprises a system for prompting a user to identify said part thickness
representations to be eliminated in each of said plurality of views and to identify a
dimension of said part to be retained in each of said plurality of views.
149. A system according to claim 143, further comprising a system for
performing a 3-D clean-up operation on said representation of said part in 3-D coordinate
space to further clean-up and eliminate extraneous information in said representation of
said part.
150. A system according to claim 149, wherein said 3-D clean-up operation
includes a process for identifying and eliminating one sided open lines that are present
in said representation of said part in 3-D coordinate space.
151. A system according to claim 149, wherein said 3-D clean-up operation
includes a process for identifying and cleaning each bendline that is present in said representation of said part in 3-D coordinate space.
152. A system according to claim 149, wherein said 3-D clean-up operation
includes a process for trimming each face that is present in said representation of said part
in 3-D coordinate space.
PCT/US1997/007473 1996-05-06 1997-05-06 Apparatus and method for generating a sheet metal bending plan WO1997042607A2 (en)

Priority Applications (2)

Application Number Priority Date Filing Date Title
DE69737913T DE69737913T2 (en) 1996-05-06 1997-05-06 DEVICE AND METHOD FOR ENTERING DATA FOR A BELOW GENERATION FOR LAYERING
EP97925441A EP1038272B1 (en) 1996-05-06 1997-05-06 Apparatus and method for data input for a bend model for a sheet metal production facility

Applications Claiming Priority (4)

Application Number Priority Date Filing Date Title
US1695896P 1996-05-06 1996-05-06
US60/016,958 1996-05-06
US08/700,671 US5971589A (en) 1996-05-06 1996-07-31 Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US08/700,671 1996-07-31

Publications (2)

Publication Number Publication Date
WO1997042607A2 true WO1997042607A2 (en) 1997-11-13
WO1997042607A3 WO1997042607A3 (en) 2000-07-13

Family

ID=26689273

Family Applications (1)

Application Number Title Priority Date Filing Date
PCT/US1997/007473 WO1997042607A2 (en) 1996-05-06 1997-05-06 Apparatus and method for generating a sheet metal bending plan

Country Status (4)

Country Link
US (4) US5971589A (en)
EP (1) EP1038272B1 (en)
DE (1) DE69737913T2 (en)
WO (1) WO1997042607A2 (en)

Families Citing this family (118)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP0744046B1 (en) 1994-11-09 2003-02-12 Amada Company Limited Intelligent system for generating and executing a sheet metal bending plan
US5828575A (en) 1996-05-06 1998-10-27 Amadasoft America, Inc. Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5971589A (en) 1996-05-06 1999-10-26 Amadasoft America, Inc. Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US6243619B1 (en) 1996-05-10 2001-06-05 Amada Company, Ltd. Control method and apparatus for plate material processing machine
US5799530A (en) 1996-12-20 1998-09-01 Amada Company, Limited Method of bending operations and bending system using the same
GB2325066B (en) * 1997-03-24 1999-06-02 Honda Motor Co Ltd Method of manufacturing dies
IT1294998B1 (en) * 1997-09-09 1999-04-27 Salvagnini Italia Spa PROCEDURE FOR THE AUTOMATIC GENERATION OF A SEQUENCE OF COMMANDS FOR SHEETS FOLDING MACHINE
US6542937B1 (en) * 1998-02-27 2003-04-01 Amada Company, Limited Apparatus and method for transferring and editing sheet metal part data
EP1060449B1 (en) 1998-03-03 2003-06-25 Amazon.Com, Inc. Identifying the items most relevant to a current query based on items selected in connection with similar queries
US7124129B2 (en) * 1998-03-03 2006-10-17 A9.Com, Inc. Identifying the items most relevant to a current query based on items selected in connection with similar queries
US6256595B1 (en) * 1998-03-04 2001-07-03 Amada Company, Limited Apparatus and method for manually selecting, displaying, and repositioning dimensions of a part model
US6144896A (en) * 1998-03-04 2000-11-07 Amada Metrecs Company, Limited Method and apparatus for designing sheet metal parts
JP3601653B2 (en) * 1998-03-18 2004-12-15 富士通株式会社 Information retrieval apparatus and method
JP3338373B2 (en) * 1998-06-05 2002-10-28 株式会社アマダ Sheet metal processing integrated support system
JP2000194726A (en) 1998-10-19 2000-07-14 Sony Corp Device, method and system for processing information and providing medium
US20050140678A1 (en) * 1999-05-10 2005-06-30 Johan Gielis Computer graphics systems and methods
US6360357B1 (en) * 1999-06-10 2002-03-19 Dassault Systems Adding code in an application during runtime to enrich object behavior
US7502027B1 (en) * 1999-09-13 2009-03-10 Solidworks Corporation Electronic drawing viewer
US6525745B1 (en) * 1999-10-25 2003-02-25 Alventive, Inc. Sheet metal geometric modeling system
US6684116B1 (en) * 2000-01-31 2004-01-27 Autodesk, Inc. Method and apparatus for incorporating features in sheet bodies
WO2001077781A2 (en) * 2000-04-07 2001-10-18 Optimation, Inc. Method and system to obtain automatic quotations from manufacturing details
US6545680B1 (en) * 2000-06-15 2003-04-08 Dessault Systemes S.A. Dual mechanism for computer-aided design
US7099803B1 (en) * 2000-09-06 2006-08-29 Proficiency Solutions Ltd. Data exchange between computer aided design systems
WO2002101689A1 (en) * 2001-06-08 2002-12-19 Anabasis Software, Llc Software-based system for educational tools
US7508946B2 (en) 2001-06-27 2009-03-24 Sony Corporation Integrated circuit device, information processing apparatus, memory management method for information storage device, mobile terminal apparatus, semiconductor integrated circuit device, and communication method using mobile terminal apparatus
US6810295B1 (en) 2001-06-29 2004-10-26 Autodesk, Inc. Method and apparatus for simplified generation and displaying of cutout features of computer aided design (CAD) model
US6985145B2 (en) * 2001-11-09 2006-01-10 Nextengine, Inc. Graphical interface for manipulation of 3D models
US7340383B2 (en) * 2001-12-20 2008-03-04 Ricoh Company, Ltd. Control device, method and computer program product for browsing data
US7469242B2 (en) * 2002-05-23 2008-12-23 The Boeing Company Central based computer network of solid models and associated data with search capability
US6845278B2 (en) 2002-08-07 2005-01-18 Kimberly-Clark Worldwide, Inc. Product attribute data mining in connection with a web converting manufacturing process
US6775585B2 (en) * 2002-10-02 2004-08-10 The Goodyear Tire & Rubber Company Method and designing and manufacturing rubber process tooling using an interface to a CAD/CAM software program
US6907666B2 (en) * 2002-12-24 2005-06-21 Delaware Capital Formation, Inc. Method of assembly of vehicle body structure
US7962855B2 (en) * 2002-12-31 2011-06-14 Apple Inc. Method of displaying an audio and/or video signal in a graphical user interface (GUI)
US7310773B2 (en) * 2003-01-13 2007-12-18 Hewlett-Packard Development Company, L.P. Removal of extraneous text from electronic documents
US20050046645A1 (en) * 2003-07-24 2005-03-03 Breton Pierre Felix Autoscaling
JP4322615B2 (en) * 2003-09-30 2009-09-02 株式会社東芝 Component information processing apparatus, component information processing method, and component information processing program provided with three-dimensional layout adjustment CAD system
US7108315B1 (en) 2003-10-14 2006-09-19 Delaware Capital Formation, Inc. Support frame for container trailer
US20050154700A1 (en) * 2003-11-26 2005-07-14 Pascal Lele System and method of costs saving procedure automation and result optimization in looping industrial environment
US20050262911A1 (en) * 2004-02-06 2005-12-01 Harry Dankowicz Computer-aided three-dimensional bending of spinal rod implants, other surgical implants and other articles, systems for three-dimensional shaping, and apparatuses therefor
DE102004035244A1 (en) * 2004-07-21 2006-02-16 Givemepower Gmbh Computer aided design system has a facility to enter drawing related information as audio input
JP2006072837A (en) * 2004-09-03 2006-03-16 Ykk Corp Product design method, product design device, product design system and product design program
US7281229B1 (en) * 2004-09-14 2007-10-09 Altera Corporation Method to create an alternate integrated circuit layout view from a two dimensional database
US7398129B2 (en) * 2004-10-07 2008-07-08 Amada Company, Limited Representation of sheet metal part models
MX2007004988A (en) * 2004-10-25 2007-06-12 Alcoa Inc Virtual programming of formed component trajectories.
US7158853B2 (en) * 2004-10-25 2007-01-02 Amada Company, Limited Pattern recognition for sheet metal part models
US7813901B2 (en) * 2004-10-25 2010-10-12 Amada Company, Limited Sketch generator for 3D sheet metal part models created by sheet metal part feature operations
US7321804B2 (en) * 2004-12-15 2008-01-22 The Boeing Company Method for process-driven bill of material
US20060129970A1 (en) * 2004-12-15 2006-06-15 Haas Martin C Systems and methods for production planning analysis using discrete event simulation
US7884818B2 (en) * 2004-12-17 2011-02-08 Kenichi Ninomiya Article design support system and method of controlling same
US7333868B2 (en) 2005-05-10 2008-02-19 Tramco, Inc. Systems and methods for designing and manufacturing engineered objects
JP4770360B2 (en) * 2005-09-26 2011-09-14 富士通株式会社 CAD program, CAD apparatus and CAD system for performing projection control processing
JP4787597B2 (en) * 2005-10-28 2011-10-05 株式会社日立製作所 Similar product data search device and search method
US20070106410A1 (en) * 2005-11-09 2007-05-10 The Boeing Company Systems and methods for production planning by visualizing products and resources in a manufacturing process
US8996151B2 (en) * 2005-11-09 2015-03-31 The Boeing Company Visualization of product build using precedence transversal method
GB2432239A (en) * 2005-11-15 2007-05-16 Toshiba Kk Building layout design support system
US7561996B2 (en) * 2006-01-13 2009-07-14 Chrysler Llc Automated dimensional drawing generating apparatus
US7996396B2 (en) * 2006-03-28 2011-08-09 A9.Com, Inc. Identifying the items most relevant to a current query based on user activity with respect to the results of similar queries
JP4856183B2 (en) * 2006-07-25 2012-01-18 富士通株式会社 Operability verification apparatus, operability verification method, and operability verification program
JP2008052648A (en) * 2006-08-28 2008-03-06 Canon Inc Analysis model generation method, program and storage medium
US8259132B2 (en) * 2006-08-29 2012-09-04 Buchheit Brian K Rotationally dependent information in a three dimensional graphical user interface
US20080082559A1 (en) * 2006-09-28 2008-04-03 Gm Global Technology Operations, Inc. Method of linking information to an electronically enabled manufactured part archive
JP4962561B2 (en) * 2007-03-20 2012-06-27 富士通株式会社 Analysis model creation device, analysis model creation method, and analysis model creation program
US8078305B2 (en) * 2007-03-23 2011-12-13 Siemens Product Lifecycle Management Software Inc. Numerical control arrangement
US20080281458A1 (en) * 2007-03-23 2008-11-13 Shengming Liu System and method for direct sheet metal unfolding
US20080255811A1 (en) * 2007-04-13 2008-10-16 Zi Qiang Sheng System and Method for Determining Surface Roughness
US20080281455A1 (en) * 2007-05-11 2008-11-13 Kenneth Swegman Materials, Operations and Tooling Interface and Methods for Managing a Remote Production Facility
JP2009054018A (en) * 2007-08-28 2009-03-12 Ricoh Co Ltd Image retrieving device, image retrieving method, and program
EP2058717B1 (en) * 2007-11-12 2011-07-20 Siemens Aktiengesellschaft Method and device for operating a machine tool
US9818071B2 (en) * 2007-12-21 2017-11-14 Invention Science Fund I, Llc Authorization rights for operational components
CN101572029B (en) * 2008-04-28 2012-01-25 鸿富锦精密工业(深圳)有限公司 System and method for simulating robot plate bending
US8620936B2 (en) * 2008-05-05 2013-12-31 The Boeing Company System and method for a data dictionary
NL2001800C2 (en) * 2008-07-14 2010-01-18 Constructiebedrijf Mous B V Metal construction manufacturing method, involves machining beam elements out of storage according to generated machining plan, and manufacturing metal construction from machined elements
KR101659576B1 (en) * 2009-02-17 2016-09-30 삼성전자주식회사 Method and apparatus for processing video image
US9378205B1 (en) * 2009-06-19 2016-06-28 Sureclinical Inc. System and method for managing and sharing pharmaceutical clinical trial regulatory documents
US8392455B2 (en) * 2009-07-02 2013-03-05 Palo Alto Research Center Incorporated Multi-interval heuristics for accelerating target-value search
US20110032254A1 (en) * 2009-08-10 2011-02-10 Amada Company, Limited Sheet metal model creation device and sheet metal model creation method
US20120232687A1 (en) * 2009-09-01 2012-09-13 Cut-Estimator Apparatus for estimating cut descriptive parameters in relation to digital cutting
US20110144784A1 (en) * 2009-12-11 2011-06-16 Siemens Product Lifecycle Management Software Inc. System and method for embedding and using intelligent product manufacturing information stored in cad model objects
JP5512321B2 (en) * 2010-02-16 2014-06-04 三協オイルレス工業株式会社 Method of designing and manufacturing cam apparatus and computer program for supporting 3D design
DE102010008478A1 (en) * 2010-02-18 2010-11-11 Harald Weisz Electronic data processing system for automated or semi-automated computer-aided design of future, technical, convenient object, has arithmetic unit allowing user to request data corresponding to job description
DE102010028135A1 (en) * 2010-04-22 2011-10-27 Trumpf Werkzeugmaschinen Gmbh + Co. Kg NC program and method for simplified post-production on a machine tool
JP5186715B2 (en) * 2010-06-14 2013-04-24 任天堂株式会社 Display control program, display control device, display control method, and display control system
US8406477B2 (en) * 2010-08-12 2013-03-26 Honeywell International Inc. System and method for constructing a three dimensional operational graphic from a two dimensional building control subsystem drawing
KR101522478B1 (en) * 2010-09-28 2015-05-21 인터내셔널 비지네스 머신즈 코포레이션 Method, program, and device for grouping plurality of elements
JP5890683B2 (en) * 2011-01-28 2016-03-22 キヤノン株式会社 Information processing apparatus and method
JP5684621B2 (en) * 2011-03-28 2015-03-18 京セラ株式会社 Electronic device, display control method, and display control program
US10535032B2 (en) * 2011-04-15 2020-01-14 International Business Machines Corporation Process model merging
US20130197863A1 (en) * 2012-01-31 2013-08-01 Tata Consultancy Services Limited Performance and capacity analysis of computing systems
US20140081599A1 (en) * 2012-09-19 2014-03-20 Josh Bradley Visualizing dimensions and usage of a space
EP2746972B1 (en) * 2012-12-20 2019-03-20 Dassault Systèmes Designing an assembly of parts in a three-dimensional scene
US9881510B2 (en) * 2012-12-21 2018-01-30 General Electric Company Testing system and method
US9569564B2 (en) * 2013-02-11 2017-02-14 Ford Global Technologies, Llc Automated cad process for creating mold packages
US9342070B2 (en) * 2013-05-31 2016-05-17 Autoform Engineering Gmbh Method and computing system for designing a sheet-metal-forming process
US9869990B1 (en) * 2013-09-12 2018-01-16 D.P. Technology Corp. Automatic positioning movement calculator
US11310056B2 (en) 2013-12-09 2022-04-19 Sureclinical Inc. System and method for high trust cloud digital signing and workflow automation in health sciences
US10046521B2 (en) * 2014-01-16 2018-08-14 Jabil Inc. Remotely-accessible additive manufacturing systems and methods
KR101694300B1 (en) * 2014-03-04 2017-01-09 한국전자통신연구원 Apparatus and method for generating 3d personalized figures
EP2927764B1 (en) * 2014-04-02 2016-06-29 Siemens Aktiengesellschaft Numerical controller with indicator for preview in case of changes to the sub-program
US9400854B2 (en) * 2014-06-03 2016-07-26 Siemens Product Lifecycle Management Software Inc. Aerospace joggle on multiple adjacent web faces with intersecting runouts
US10817526B2 (en) 2014-07-16 2020-10-27 Machine Research Corporation Systems and methods for searching a machining knowledge database
US10466681B1 (en) * 2014-09-02 2019-11-05 Machine Research Corporation Systems and methods for machining knowledge reuse
US10390884B2 (en) 2015-06-30 2019-08-27 DePuy Synthes Products, Inc. Methods and templates for shaping patient-specific anatomical-fixation implants
JP6565475B2 (en) * 2015-08-21 2019-08-28 富士ゼロックス株式会社 Bending frequency calculation system and bending frequency calculation program
US11328234B2 (en) 2015-12-11 2022-05-10 Sureclinical Inc. Interactive project progress tracking interface
US9965678B2 (en) * 2016-06-29 2018-05-08 Konica Minolta Laboratory U.S.A., Inc. Method for recognizing table and flowchart in document images
USD839669S1 (en) * 2016-11-23 2019-02-05 Fusion Tech Integrated, Inc. Oven corner
CN110199280B (en) * 2017-01-24 2023-07-07 西门子工业软件有限公司 Method and system for multi-view computer aided design including edit operation propagation across views while ensuring constraint consistency
US11059229B2 (en) * 2017-01-27 2021-07-13 Hewlett-Packard Development Company, L.P. Rules for printing three-dimensional parts
US20180225408A1 (en) * 2017-02-03 2018-08-09 Ignitor Labs, LLC System and method for interactive modeling and analysis of 3-d digital assemblies
JP6777672B2 (en) * 2018-04-03 2020-10-28 Dmg森精機株式会社 Information processing equipment, information processing methods and information processing programs
US20190313077A1 (en) * 2018-04-08 2019-10-10 Vefxi Corporation Virtual reality environment
CN108764068A (en) * 2018-05-08 2018-11-06 北京大米科技有限公司 A kind of image-recognizing method and device
US20220299978A1 (en) 2019-09-21 2022-09-22 Amada Co., Ltd. Processing program creation device and processing program creation method
US11591802B1 (en) 2020-02-28 2023-02-28 Material Control, Inc. Modular access system
US20210303743A1 (en) * 2020-03-24 2021-09-30 Protolabs, Inc. Methods and systems for generating an instant design for manufacturability of a part at a computing device
US11947491B2 (en) 2020-12-22 2024-04-02 Paperless Parts, Inc. Apparatus and methods for geometric searching
WO2023107118A1 (en) * 2021-12-10 2023-06-15 Siemens Industry Software Inc. Method of selecting a component in a cad model
US11574084B1 (en) 2022-01-31 2023-02-07 Protolabs, Inc. Methods and systems for geometric analysis of a part for manufacture

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4912644A (en) * 1986-12-02 1990-03-27 Oki Electric Industry Co., Ltd. Method of and apparatus for unfolding a sheet metal part employing a CAD apparatus
EP0402475A1 (en) * 1988-12-24 1990-12-19 Fanuc Ltd. Method of determining expanded shape of a product in a cad system
EP0419013A2 (en) * 1989-09-22 1991-03-27 Hewlett-Packard Company Apparatus and method for computer-aided design of sheet metal fabricated parts
US5029462A (en) * 1988-08-05 1991-07-09 Amada Company, Limited Method of bending a workpiece including setting a bending process, and preparing bending data

Family Cites Families (43)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JPH0677776B2 (en) 1986-07-30 1994-10-05 株式会社アマダ Method for determining bending order in NC bending machine
IT1205162B (en) 1986-06-20 1989-03-15 Amada Co Ltd MULTI-STAGE BENDING MACHINE
JPH07121415B2 (en) 1986-12-15 1995-12-25 株式会社 アマダ Folding machine control system
JPH07121418B2 (en) 1986-12-16 1995-12-25 株式会社アマダ Control data communication system for folding machine
JPH07121416B2 (en) 1986-12-16 1995-12-25 株式会社アマダ Bending order automatic determination device
JPH07121417B2 (en) 1986-12-16 1995-12-25 株式会社アマダ Folding system
JPH0732933B2 (en) 1986-12-16 1995-04-12 株式会社アマダ Bending die automatic selection method
ES2086290T3 (en) * 1987-04-14 1996-07-01 Northrop Grumman Corp MANUFACTURING SYSTEM USING GRAPHIC MODELS IN THREE DIMENSIONS.
GB2211002B (en) 1987-12-15 1992-01-08 Amada Co Ltd Device and method for controlling a manipulator for a plate bending machine
JP2572264B2 (en) 1988-06-06 1997-01-16 本田技研工業株式会社 Inspection method and inspection line for automatic transmission and transport pallet for automatic transmission
JP2771544B2 (en) * 1988-06-07 1998-07-02 株式会社アマダ Process display confirmation device for mold and bending order
JP2624514B2 (en) * 1988-06-07 1997-06-25 株式会社アマダ Method and apparatus for setting bending mold and bending order
JP2677828B2 (en) * 1988-07-05 1997-11-17 株式会社アマダ Bending die automatic determination method
JPH0215828A (en) * 1988-07-05 1990-01-19 Amada Co Ltd Schedule data generating method for bending machine
JPH07104701B2 (en) * 1989-05-08 1995-11-13 三菱電機株式会社 CAD / CAM device
EP0397904B1 (en) * 1989-05-19 1994-07-27 Hewlett-Packard GmbH Method for generating graphical models and computer aided design system
US5237647A (en) * 1989-09-15 1993-08-17 Massachusetts Institute Of Technology Computer aided drawing in three dimensions
US5089970A (en) * 1989-10-05 1992-02-18 Combustion Engineering, Inc. Integrated manufacturing system
JP2849168B2 (en) * 1990-06-29 1999-01-20 オ−クマ株式会社 Numerical control information creation device
US5396265A (en) * 1990-09-17 1995-03-07 Massachusetts Institute Of Technology Three-dimensional tactile computer input device
EP0485766A3 (en) * 1990-11-06 1993-06-30 Biomechanics Corporation Of America Anthropometric computer aided design method and system
US5341243A (en) * 1991-06-04 1994-08-23 Canon Kabushiki Kaisha Zoom lens of rear focus type
JP3228766B2 (en) 1991-11-01 2001-11-12 龍治 江守 Video teaching equipment for processing machines
JP2828151B2 (en) * 1992-01-10 1998-11-25 龍治 江守 Sheet metal processing machine
US5297054A (en) * 1992-04-03 1994-03-22 General Motors Corporation Expert system for automically generating gear designs
EP0664186A4 (en) * 1992-10-09 1995-09-20 Machining information determining system and method, and machining process information determining system and method.
US5315522A (en) * 1992-11-06 1994-05-24 Kenneth A. Kauffman Table bender controller
JPH06274219A (en) 1993-03-17 1994-09-30 Mutoh Ind Ltd Nc working data generating device in cad device
US5434791A (en) * 1993-06-29 1995-07-18 Electronic Data Systems Corporation Product structure management
US5429682A (en) * 1993-08-19 1995-07-04 Advanced Robotics Technologies Automated three-dimensional precision coatings application apparatus
US5453933A (en) * 1993-09-08 1995-09-26 Hurco Companies, Inc. CNC control system
JPH07121418A (en) * 1993-10-25 1995-05-12 Nippon Telegr & Teleph Corp <Ntt> File management method
US5485390A (en) * 1993-11-30 1996-01-16 The United States Of America As Represented By The Secrectary Of The Air Force Inductive-deductive process design for machined parts
EP0744046B1 (en) * 1994-11-09 2003-02-12 Amada Company Limited Intelligent system for generating and executing a sheet metal bending plan
US5969973A (en) 1994-11-09 1999-10-19 Amada Company, Ltd. Intelligent system for generating and executing a sheet metal bending plan
US5835684A (en) * 1994-11-09 1998-11-10 Amada Company, Ltd. Method for planning/controlling robot motion
US5971589A (en) 1996-05-06 1999-10-26 Amadasoft America, Inc. Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5886897A (en) * 1996-05-06 1999-03-23 Amada Soft America Inc. Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5822207A (en) 1996-05-06 1998-10-13 Amadasoft America, Inc. Apparatus and method for integrating intelligent manufacturing system with expert sheet metal planning and bending system
US5828575A (en) * 1996-05-06 1998-10-27 Amadasoft America, Inc. Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5864482A (en) 1996-05-06 1999-01-26 Amadasoft America, Inc. Apparatus and method for managing distributing design and manufacturing information throughout a sheet metal production facility
US5799530A (en) 1996-12-20 1998-09-01 Amada Company, Limited Method of bending operations and bending system using the same
US6701208B2 (en) * 2001-09-04 2004-03-02 Amada Company, Limited. Apparatus and method of proposing bending sequences and bending tools for a metal plate part

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4912644A (en) * 1986-12-02 1990-03-27 Oki Electric Industry Co., Ltd. Method of and apparatus for unfolding a sheet metal part employing a CAD apparatus
US5029462A (en) * 1988-08-05 1991-07-09 Amada Company, Limited Method of bending a workpiece including setting a bending process, and preparing bending data
EP0402475A1 (en) * 1988-12-24 1990-12-19 Fanuc Ltd. Method of determining expanded shape of a product in a cad system
EP0419013A2 (en) * 1989-09-22 1991-03-27 Hewlett-Packard Company Apparatus and method for computer-aided design of sheet metal fabricated parts

Non-Patent Citations (3)

* Cited by examiner, † Cited by third party
Title
"METHOD FOR UNDERSTANDING DRAWING ATTRIBUTES FOR 3D MODELS" IBM TECHNICAL DISCLOSURE BULLETIN, vol. 37, no. 7, 1 July 1994, pages 99-104, XP000455452 *
GU P ET AL: "PRODUCT MODELLING USING STEP" COMPUTER AIDED DESIGN, vol. 27, no. 3, 1 March 1995, pages 163-179, XP000529629 *
YUAN-JYE TSENG ET AL: "RECOGNIZING MULTIPLE INTERPRETATIONS OF INTERACTING MACHINING FEATURES" COMPUTER AIDED DESIGN, vol. 26, no. 9, 1 September 1994, pages 667-688, XP000468868 *

Also Published As

Publication number Publication date
US7197372B2 (en) 2007-03-27
US6327514B1 (en) 2001-12-04
DE69737913T2 (en) 2008-01-03
US7266419B2 (en) 2007-09-04
EP1038272B1 (en) 2007-07-11
US20060106757A1 (en) 2006-05-18
US20020038163A1 (en) 2002-03-28
DE69737913D1 (en) 2007-08-23
EP1038272A2 (en) 2000-09-27
US5971589A (en) 1999-10-26
WO1997042607A3 (en) 2000-07-13

Similar Documents

Publication Publication Date Title
EP1038272A2 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5828575A (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
US5864482A (en) Apparatus and method for managing distributing design and manufacturing information throughout a sheet metal production facility
US5886897A (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
WO1997042608A9 (en) Apparatus and method for generating a sheet-metal bend model
US6898560B1 (en) Maintaining a computer-generated design model
CA2541951A1 (en) Method of computer-aided design of a modeled object having several faces
WO1999013433A1 (en) Automatically generating three-dimensional solids from two-dimensional view sets
JP3884195B2 (en) Apparatus and method for distributing design and fabrication information throughout a sheet metal fabrication facility
US5748197A (en) Dynamic computation of a line segment arrangement using finite precision arithmetic for use in a processor controlled system
JP3308869B2 (en) Parts display image operation system and method
EP1830323A2 (en) Apparatus and method for managing and distributing design and manufacturing information throughout a sheet metal production facility
JP3766857B2 (en) 3D model development support system

Legal Events

Date Code Title Description
AL Designated countries for regional patents

Kind code of ref document: A2

Designated state(s): AT BE CH DE DK ES FI FR GB GR IE IT LU MC NL PT SE

121 Ep: the epo has been informed by wipo that ep was designated in this application
DFPE Request for preliminary examination filed prior to expiration of 19th month from priority date (pct application filed before 20040101)
WWE Wipo information: entry into national phase

Ref document number: 1997925441

Country of ref document: EP

AL Designated countries for regional patents

Kind code of ref document: A3

Designated state(s): AT BE CH DE DK ES FI FR GB GR IE IT LU MC NL PT SE

WWP Wipo information: published in national office

Ref document number: 1997925441

Country of ref document: EP

WWG Wipo information: grant in national office

Ref document number: 1997925441

Country of ref document: EP