Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Electrical Engineering Software Lab - Technion 3D Object Retrieval Project Spring semester 2001/02 Developers Iddo Simhon Omer Boker Supervisor George Leifman Table of Contents Chapter No Subject Page 1 1.1 1.2 1.3 Introduction Problem description Project’s goals Summary of project’s solution 3 3 3 4 2 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.2 2.2.1 2.2.2 Solution description System design System general structure The client side The server side In the middle (client – server) Main classes The client side The server side 5 5 5 6 20 22 24 24 25 3 4 5 6 Special design solutions Results References User’s guide 27 29 29 30 2 1. Introduction 1.1 Problem Description The 3D Object retrieving subject is under massive development these days. Several projects have been done lately, and there are more to come. A lot of the projects dealing with this subject include development of 3D object retrieving algorithms, but most projects needed some of the software to be developed, mainly to have a more friendly interface for a user. There was a need for a system that will generalize that subject, meaning a system that will include the similar parts of object retrieving programs, and will enable to easily add more algorithms. Another problem was that the storage space needed for a database of 3D objects is too big for installing on each user’s computer. There was a need for a distributed software that will enable to store the 3D objects data base in one computer (that will be the server) and will enable each other computer (client) to communicate with the server, and perform the retrieving tasks without the need to store the 3D objects files locally. 1.2 Project’s Goals The project’s main goal is to create a general distributed system for 3D objects retrieval. It does it’s task by encapsulating the algorithms themselves in a general interface, in a way that the calling environment doesn’t care which algorithm is activated. This means that it acts the same for each algorithm, and more important, will act the same with future algorithm that may be added. Another goal is to enable operation of the 3D object retrieval in a distributed environment, which means that there will be only one machine that will serve as the server. This server will be the only one that will have the objects themselves – the database, and the only one that will execute the 3D algorithms. Each user of the system, will have to install only a client program, that will know how to communicate with the server. This client program will be written in Java, so it can be executed from any possible platform. 3 1.3 Summary of the project’s solution The solution for the above requirements was to build two applications – a server application and a client application. Each application was designed according to the tasks it should execute. The server application should handle requests from many clients, so it was written as multi-threaded application. It includes all the 3D objects retrieval algorithms, and a general interface for using them. The client application should be able to run on each platform, so it was written in Java. It should also have the capability of presenting the 3D objects, this was achieved by using Java 3D. The client application should also enable the user to use all the ‘expected’ program features. The connection between the two applications (client-server) is done by TCP/IP. The TCP/IP protocol is a good way for communicating between the two programming languages (server uses C++, client uses Java) and is also a natural and effective way for connecting between the two applications. Note that in real situation, the ratio between the running server programs to the running client programs is one to many, respectively, as in regular clientserver models. 4 2. Solution Description This chapter will explain in detail the design of the project’s parts – the client and the server, and the main technologies that are being used in the project. 2.1 System Design 2.1.1 System General Structure As described above, basically the system structure is divided to server and client. The server includes the following features: The 3D object retrieval algorithms. General interface that wraps these algorithms so that they can be used transparently. Multi-Threading handling, in so that the server can serve many clients. The ability to send and receive data through sockets. Each action that the user can operate, has a defined protocol both sides. The client includes the next features: Graphical user interface that enables the user to operate the system, which means using the system features. The ability to present 3D objects using Java 3D. The ability to send and receive data through sockets. Each action that the user can operate, has a defined protocol in both sides. Client Socket Listening Socket Client A Handling Socket Client Socket Handling Socket Server 5 Client B 2.1.2 The Client Side The client side is written in Java. It includes 3 main parts: Graphical User Interface. Socket handling for communicating with the server. Presentation of 3D objects by using Java 3D. The graphical user interface (GUI) is based on the Swing classes. The GUI enables the user to operate the system’s features – retrieving objects, perform the compares operations, upload files to the server, download files from the server, change the system settings and so on. It also presents icons for the user, so he can select from, and show 3D shapes. The swing classes encapsulates all the GUI components views, and helps in handling the GUI events (user mouse clicks) by providing interface that we implemented in order to perform actions when the user clicks on buttons. The GUI also includes 50 icons of shapes which are changing according to the client’s actions. 6 The communication handling is done by using java sockets. Each operation that requires communication with the server, requires a socket. When an operation like this is activated, a new socket is created, in order to send and receive data to/from the server. Each operation has its own protocol. See the client’s classes documentation for details. The presentation of the objects is done using the Java 3D package. The Java 3D package purpose is to enable creation and presentation of 3D scenes on various platforms. In our project, we have to create a scene of one shape each time, and we have to take the data for creating the shape from a file. In our implementation, we need a .obj 3D file for presenting the shape. We use the Java 3D capabilities for lightning the shape, and for moving it according to the mouse movements. Read more about the Java 3D capabilities and class hierarchy in the next section. 7 2.1.2.1 The Java3D Technology This section includes a summery of the important things that Java 3D can do, some of them we used for our project. Introduction Internet technologies, and, in particular the Java הlanguage have brought about a fundamental change in the way that applications are designed and deployed. Java’s “write once, run anywhere” model has lessened the complexity and cost normally associated with producing software on multiple distinct hardware platforms. With Java, the browser paradigm has emerged as a compelling way to produce applications for the Internet and the corporate intranet. As new classes of applications emerge for the Web environment, there is increasing pressure for full multimedia capabilities to become seamlessly integrated into the browser paradigm. Application developers are demanding a small number of high-level interfaces to work with and users prefer a seamless environment which is easy to operate and maintain. In addition to software innovations, ASIC technology and high levels of integration have made accelerated 3D graphics- and multimedia-capable hardware affordable. High end graphics features, previously only available on specialized graphics workstations, are now widely available on low-cost platforms, making them available for new kinds of applications. The Need for Integrated Web-based Multimedia In the past, integration of multimedia technology like audio, video, and 3D graphics into Web-based applications has required the use of external applications (or “plug-ins”) to handle data which the browser wasn’t capable of interpreting or displaying. For example, VRML (Virtual Reality Modeling Language) scene navigation generally requires that a separate VRML plug-in application be installed on the client system. Though widely used, plug-ins are non-flexible in that they represent separately compiled, platform-specific code which must be individually installed on each client platform. From the client perspective, plug-ins are poorly integrated into the browser environment since they are a separate application and often operate in a separate window from the browser. Additionally, useful plug-ins may only be available for the more popular client platforms. 8 Java 3D As a part of Java Media, the Java 3D API is an application programming interface used for writing stand-alone three-dimensional graphics applications or Web-based 3D applets. It gives developers high level constructs for creating and manipulating 3D geometry and tools for constructing the structures used in rendering that geometry. With Java 3D constructs, application developers can describe very large virtual worlds, which, in turn, are efficiently rendered by Java 3D. The Java 3D specification is the result of a joint collaboration between Silicon Graphics, Inc., Intel Corporation, Apple Computer, Inc., and Sun Microsystems, Inc. All had advanced, retained mode APIs under active internal development, and were looking at developing a single, compatible, cross-platform API in Java. The Java 3D API draws its ideas from the considerable expertise of the participating companies, from existing graphics APIs, and from new technologies. Java 3D’s low-level graphics constructs synthesize the best ideas found in low-level APIs such as Direct3D ה, OpenGL ה, QuickDraw3D rehgih s’D3 avaJ ,ylralimiS .LGX dna , ה-level constructs leverage the best ideas found in several modern scene graph-based systems. Java 3D also introduces some concepts not commonly considered part of the graphics environment, such as 3D special sound to provide a more immersive experience for the user. Markets and Applications Java 3D is designed as a high-level platform-independent 3D graphics programming API and is amenable to very high performance implementations across a range of platforms. Java 3D will scale gracefully as the rendering speed and capabilities of the underlying 3D hardware increase by orders of magnitude over time. Java 3D is targeted at a wide spectrum of 3D application environments from small to very large virtual universes. • Browsers Providing Java 3D support in Web browsers will obviate the need for separately compiled plug-ins and will enable full integration of 3D navigation completely within the browser environment. • Virtual Reality systems Java 3D’s scene-graph based model makes it ideal for Virtual Reality systems and other applications that wish to represent and navigate complex 3D worlds. 9 • 3D games Though many programmers will continue to implement games in low-level assembly code, Java 3D includes many features that enable high performance 3D games to be written in a platform-independent fashion. • CAD systems Both Web-based CAD applications and stand-alone MCAD systems represent a key opportunity for Java 3D. • 3D logos, Web pages (graphic designers) Tools that enable Java 3D output are anticipated for Web designers who wish to include interactive 3D representations, or dynamic 3D logos into Web page design. • VRML Implementations Though Java 3D does not support VMRL directly, it is expected that applications will be developed which provide support for loading the various VRML formats into Java 3D representations. • Authoring Systems Though Java 3D is not an authoring environment, and does not provide built-in authoring tools, it is quite likely that independent software suppliers will build authoring systems that generate Java 3D applications as output. Java 3D Overview Historically, 3D graphics programmers have needed to wring every last ounce of performance from their graphics hardware in order to obtain a high degree of visual realism. Developers have often had to leverage extensive knowledge of underlying hardware details in order to obtain maximum performance from a given graphics accelerator. Even low-level cross-platform APIs, like OpenGL, have required a high degree of programming expertise in order to exact optimized performance from different hardware platforms. These realities have resulted in a difficult and expensive development process which has mandated platform-specific development efforts — leaving few resources to focus on application functionality. 10 A Platform Independent 3D API Java 3D represents an evolution to a standard, high-level 3D API that yields a high degree of interactivity while preserving true platform independence. Java 3D Design Goals Java 3D was designed to satisfy the following goals: • High Performance Many design decisions were made so that Java 3D implementations could deliver the highest level of performance to application users. In particular, when trade-offs were made, the alternative that benefited runtime execution was chosen. • Rich set of 3D features Java 3D was designed to provide a rich set of features for creating interesting 3D worlds, tempered by the need to avoid non-essential or obscure features. Features that could be written in Java and layered on top of Java 3D were not included. • High-level, Object-oriented paradigm Java 3D was designed to offer a high-level, object-oriented, programming paradigm that enables developers to rapidly deploy sophisticated applications and applets. • Wide Variety of File Formats Support for run-time loaders was included to allow Java 3D to accommodate a wide variety of file formats such as vendor-specific CAD formats, interchange formats, VRML 1.0, and VRML 2.0. High Performance Java 3D’s scene graph programming model (described later in this document) allows the Java 3D API to perform mundane tasks (traversal of the scene graph, management of state attribute changes, etc.), thereby simplifying the job for the application. Java 3D does this without sacrificing performance. At first glance, it might appear that this high-level approach would create more work for the API. However, it actually has the opposite effect. Java 3D’s higher level of abstraction not only changes the amount, but more importantly, the kind of work that the API must perform. Java 3D is freed from the constraints found in interfaces with a lower level of abstraction and allows introduction of optimizations not possible with these lower-level APIs. 11 Additionally, leaving the details of rendering to Java 3D allows it to tune the rendering to the underlying hardware. For example, relaxing the strict rendering order imposed by other APIs allows parallel traversal of the scene graph as well as parallel rendering. Knowing which parts of the scene graph cannot be modified at runtime allows Java 3D to flatten the tree, pre-transform geometry, or represent the geometry in a native hardware format without the need to keep the original data. Layered Implementation Besides optimizations at the API level, one of the more important factors that determines the performance of Java 3D is the time it takes to render the visible geometry. To optimize rendering, Java 3D implementations are layered to take advantage of the native, low-level API that is available on a given system. In particular, Java 3D implementations that utilize OpenGL, Direct3D, and QuickDraw3D will be available. This means that Java 3D rendering will be accelerated across the same wide range of systems that are supported by these lower-level APIs. Target Hardware Platforms Java 3D is aimed at a wide range of 3D-capable hardware and software platforms, from low cost PC game cards and software renderers, through midrange workstations, all the way up to very high-performance, specialized, 3D image generators. It is expected that Java 3D implementations will provide useful rendering rates on most modern PCs, especially those with 3D graphics accelerator cards. On mid-range workstations, Java 3D is expected to provide applications with nearly full-speed hardware performance. Finally, Java 3D was designed to scale as the underlying hardware platforms increase in speed over time. Tomorrow’s 3D PC game accelerators will support more complex virtual worlds than the high-priced workstations of a few years ago. Java 3D is prepared to meet this increase in hardware performance. Programming Paradigm Java 3D provides several basic classes that are used to construct and manipulate a scene graph, and to control viewing and rendering. The Scene Graph Programming Model Java 3D’s scene graph-based programming model provides a simple and flexible mechanism for representing and rendering potentially complex 3D environments. The scene graph contains a complete description of the entire 12 scene, or virtual universe. This includes the geometric data, the attribute information, and the viewing information needed to render the scene from a particular point of view. The Java 3D API improves on previous graphics APIs by eliminating many of the bookkeeping and programming chores that those APIs impose. Java 3D allows the programmer to think about geometric objects rather than about triangles—about the scene and its composition rather than about how to write the rendering code for efficiently displaying the scene. Java 3D View Model Java 3D introduces a new view model that takes Java’s vision of “write once, run anywhere” and generalizes it to include display devices and six-degree-offreedom input peripherals such as headtrackers. An application or applet written using the Java 3D view model can render images to a broad range of display devices including flat screen displays, portals/caves, and head-mounted displays all without modification to the code. The same application or applet, (once again without modification) can render stereoscopic views and can take advantage of the input from a headtracker to control the rendered view. Java 3D’s view model achieves this versatility by cleanly separating the virtual and the physical world. This model distinguishes between how an application positions, orients and scales a ViewPlatform object (a viewpoint) within the virtual world and how Java 3D’s renderer constructs the final view from that viewpoint’s position and orientation. The application controls the ViewPlatform’s position and orientation while the renderer computes what view to render using this position and orientation, a description of the end-user’s physical environment, and the user’s position and orientation within the physical environment. The Camera Based Model Most low-level APIs utilize a Camera-based view model which emulates a camera in the virtual world. Developers must continuously reposition a simulated camera in such an API to emulate a human in the virtual world. Camera-based view models give developers control over all rendering parameters. This control make sense when dealing with custom applications but is less useful when dealing with systems such as viewers or browsers that load and display whole worlds as a single unit, or that let their end-users view, navigate, display, and even interact with that world. Making the application control all rendering parameters is problematic in 13 systems where the physical environment dictates some of the view parameters: For example, a head-mounted display (HMD), where the optics of the headmounted display directly determine the field-of-view that the application should use. Different HMDs have different optics, and hard-wiring such parameters into an application or allowing end-users to vary these parameters are poor solutions. Additionally, view parameters change as a function of the user’s head position with an HMD. The specification of a world and a predefined flight path through that world may not exactly specify an end-user’s view should the user look to the side and change the view. Java 3D’s view model incorporates the appropriate abstractions to compensate automatically for such variability in end-user hardware environments. Camera Based View Model Support In order to assist with porting existing applications, Java 3D provides a compatibility mode which enables a camera-based view model. With a simple function-call, applications can enable compatibility mode for room-mounted, non head-tracked display environments. It should be noted that use of these view compatibility functions will disable some of Java 3D’s view model features and will limit portability. Input The java.awt package of classes already contains an abstraction for common desktop interaction peripherals like keyboards and mice. Java 3D uses that implementation for simple devices rather than creating a separate, incompatible I/O model. However, since Java 3D provides support for a variety of continuous input devices such as six-degree-of-freedom (6DOF) trackers and joysticks, a new input model was required. For these time-critical devices, Java 3D introduces a new real-time class of I/O device which provides for very low latency. In real-time graphics systems, low latency can be more important than missing an event since an event more than a few 30th’s of a second old may no longer be of any interest (particularly if it tracks a user’s current head position). Java 3D abstracts the idea of a tracking device or joystick in the form of a sensor. A sensor consists of a time-stamped sequence of input values and the state of any buttons or switches on the sensor at the time that Java 3D sampled the value. Behavior, Animation, and Picking Behavior nodes provide the means for animating objects, processing keyboard and mouse inputs, reacting to movement, and enabling and processing pick 14 events. Behavior nodes contain Java code and state variables. The Java code in a Behavior node can interact with Java objects, change node values within a Java 3D scene graph, change internal state, and perform other computations. Simple behaviors can add surprisingly interesting effects to a scene graph. For example, a rigid object can be animated by using a behavior node to repetitively modify the TransformGroup node that points to the object. Alternatively, a behavior node can track the current position of a mouse and modify portions of the scene graph to implement picking. Behavior Object A Behavior leaf node object contains a scheduling region and two methods: an initialization method called once when the behavior becomes “live” and a processStimulus method called whenever appropriate by the Java 3D behavior scheduler. The behavior object will also contain whatever state information the Behavior code requires. The scheduling region defines a spatial volume that serves to enable the scheduling of Behavior nodes. A Behavior node is active (can receive stimuli) whenever a ViewPlatform’s activation volume intersects a Behavior object’s scheduling region. Only active behaviors can receive stimuli. The initialization method allows a behavior object to initialize its internal state and specify its initial wakeup condition(s). Java 3D invokes a behavior’s initialization code when the behavior’s containing BranchGroup node is added to the virtual universe. The processStimulus method receives and processes a behavior’s ongoing messages. Java 3D invokes a behavior node’s processStimulus-method when a ViewPlatform’s activation volume intersects a behavior object’s scheduling region and one of the behavior’s wakeup criterion is satisfied. The processStimulus method performs its computations and actions (possibly including the registration of state change information that could cause Java 3D to wake other behavior objects), establishes its wakeup conditions, and exits. Scheduling As a virtual universe grows large, Java 3D must carefully husband its resources to ensure adequate performance. In a 10,000-object virtual universe with 400 or so behavior nodes, a naive implementation of Java 3D could easily end up consuming the majority of its compute cycles by executing the behaviors associated with the 400 behavior objects before it draws a frame. In such a situation, the frame rate could easily drop to unacceptable levels. Java 3D mitigates the problem of a large number of behavior nodes in a highpopulation virtual universe through execution culling—choosing only to invoke those behaviors that have high relevance. 15 In a universe consisting of a large number of Behavior nodes controlling a similar number of objects, only a few of the controlled objects are typically visible at any one time. The sizeable fraction of the behavior nodes which are associated with non-visible objects, need never execute. The remaining, substantially smaller number of behavior objects associated with visible objects, must be executed. Java 3D requires each behavior to have a scheduling region and to post a wakeup condition. Together a behavior’s scheduling region and wakeup criterion provide Java 3D’s behavior scheduler with sufficient domain knowledge to selectively prune behavior invocations and only invoke those behaviors that absolutely need to execute. Execution Culling Java 3D finds all scheduling regions associated with behavior nodes and constructs a scheduling-volume tree. It also creates an AND-OR tree containing all the behavior node wakeup criterion. These two data structures provide the domain knowledge Java 3D needs to prune unneeded behavior execution. Java 3D must track a behavior’s activation conditions only if a ViewPlatform object’s activation volume intersects with that behavior object’s scheduling region. If the ViewPlatform object’s activation volume does not intersect with a behavior’s scheduling region, Java 3D can safely ignore that behavior’s wakeup criterion. In essence, the Java 3D scheduler performs the following checks: 1. Find all Behavior objects with scheduling regions that intersect the ViewPlatform object’s activation volume. 2. For each Behavior object that falls within the ViewPlatform’s activation volume, check the Behavior’s WakupCondition 3. Schedule that behavior object for execution if the WakupCondition is true Java 3D’s behavior scheduler executes those behavior objects that have been scheduled by calling the behavior’s processStimulus method. Predefined Behaviors — Interpolators Java 3D provides a number of predefined behaviors. These predefined behaviors are known as Interpolators because they smoothly interpolate between a minimum and a maximum value. The Java 3D API provides interpolators for a number of functions: for manipulating transformations within a TransformGroup, for modifying the values of a Switch node, and for modifying Material attributes such as color and transparency. 16 LOD Behaviors The LOD (Level of Detail) behavior node is an abstract behavior class that operates on a list of Switch group nodes to select one of the children of the Switch node. Specializations of the LOD abstract behavior node implement various level-of-detail policies. For example, the Distance LOD behavior node implements a distance-based LOD policy by selecting one of the Switch nodes’ children based on distance from the viewer. BillBoard Behaviors The Billboard behavior node operates on a TransformGroup node to specify a transform that always aligns itself perpendicular to a specified worldcoordinate axis or to a viewer’s view vector. This transform is independent of transforms above the specified node in the scene graph. Billboard nodes provide the most benefit for complex, roughly-symmetric objects. In a typical application, a quadrilateral that contains a texture of a tree might be held perpendicular to the user. Picking Behavior nodes also provide the means for building developer-specific picking semantics. An application developer can define custom picking semantics using Java 3D’s behavior mechanism. For example, the developer might wish to define pick semantics that use a mouse to shoot a ray into the virtual universe from the current viewpoint, find the first object along that ray, and highlight that object when the user releases the mouse button. Rendering Model, Rendering Modes, and Execution Path Java 3D assumes a double-buffered, true-color, and Z-buffered rendering model. This was done primarily to avoid creating multiple APIs and incompatible programs to support indexed and true color, or Z-buffered and non Z-buffered environments. Note that this set of minimal requirements is for the Java 3D rendering model, and does not necessarily describe hardware necessary to run a Java 3D application. The rendering model simply describes Java 3D’s frame of reference and defines those properties that must be present in a low-level API in order to use it as a base for a Java 3D implementation. How a low-level API implements that functionality is arbitrary to Java 3D. Rendering Modes Java 3D includes three different rendering modes: immediate mode, retained 17 mode, and compiled-retained mode. Each successive rendering mode allows Java 3D more freedom in optimizing an application’s execution. Most Java 3D applications will want to take advantage of the convenience and performance benefits that retained and compiled-retained modes provide. • Immediate Mode Immediate mode leaves very little room for optimization. Even so, Java 3D has raised the level of abstraction. An application must provide a Java 3D draw method with a complete set of points, lines, or triangles. Of course, the application can build these lists of points, lines, or triangles in any manner it chooses. • Retained Mode Retained mode requires an application to construct a scene graph and specify which elements of that scene graph may change during rendering. The scene graph describes the objects in the virtual universe, the arrangement of those objects, and how the application animates those objects. • Compiled-Retained Mode Compiled-retained mode, like retained mode, requires the application to construct a scene graph and specify which elements of the scene graph may change during rendering. Additionally, the application can compile some, or all, of the subgraphs that make up a complete scene graph. Java 3D compiles these graphs into an internal format. The compiled representation of the scene graph bears little resemblance to the original tree structure provided by the application but is functionally equivalent. Java 3D Runtime Execution Path Once a Java 3D program has been created, the following steps are taken by the program to create the scene graph elements and link them together. Java 3D will then render the scene graph and display it in a window on the screen: 1. Create the Canvas3D and View objects. 2. Establish the virtual universe and high-res Locale 3. Construct the scene graph elements. 4. Link them together to form the two subgraphs. 5. Optionally compile the subgraphs. 6. Insert the two subgraphs into the Locale. The Java 3D renderer then starts running in an infinite loop. The renderer 18 conceptually performs the following operations: while(true) { Process input If (request to exit) break Perform Behaviors Traverse the scene graph and render visible objects } Cleanup and exit Sound Model Java 3D uses Java’s standard audio API in order to provide general sound and midi support. Because Java 3D is the only Java API that includes support for headtrackers, parameterization of a user’s physical head, generalized transformations, and other such concepts, Java 3D adds additional support for fully spatialized audio. Vector Math Library Java 3D defines a number of additional objects that are used in the construction and manipulation of other Java 3D objects. These objects provide low-level storage and manipulation control for users. They provide methods for representing vertex components (e.g., color and position), volumes, vectors, and matrices. The tuple and matrix math classes are not part of Java 3D per se, but they are needed by Java 3D and are defined here for convenience. Java 3D uses these classes internally and also makes them available for use by applications. These classes will be delivered in a separate java.vecmath package for use with other Java APIs. Geometry Compression Java 3D allows programmers to specify geometry using a binary geometry compression format. This compression format is used with APIs other than just Java 3D, and can be used both as a run-time in-memory format for describing geometry, as well as a storage and network format. Using geometry compression allows geometry to be represented in an order of magnitude less space than most traditional 3D representations, with very little loss in object quality. Parameters exist to allow the user to trade off space versus quality by adjusting the degree of loss in the compression algorithm. Like the vector mathematics library, geometry compression is provided with the Java 3D specification but is likely to become its own specification over time. 19 2.1.3 The Server Side The server includes the real working functions of the system. The 3D comparing algorithms resides and executes in the server, the project supervisor can change the algorithms or add algorithms at any given time. In the server, resides a big database of shapes, initialized by the writers of the project and the project supervisor. This database can be edited and changed by the supervisor at any given time, and shapes can be added (uploaded) or downloaded by any client easily. In addition, the server manages all the clients requests, and performs the work needed in order to send the clients the relevant data. The multithreading model, the 3D shape retrieval and the sockets programming are discussed in detail in the next sections, but the main features of the server are as follows: Accepting a request using a listening thread. Creating a new thread to handle the request, and connecting it to the client. From now on, the listening thread doesn’t care about that request. It returns to listen, and to accept other requests. The new created thread, the responding thread, executes code according to the action performed by the client. Each required action has it’s own protocol. This protocol is executed by the created thread and the client. The client sends the responding thread the data that it needs for doing its job, and the responding thread sends the client the required data. After finishing doing its job, the responding thread exists. 2.1.3.1 The Multithreading Model and the Server State Mode The multithreading model that is used in this project is common for clientserver systems: The server side executes a listening thread that waits for requests from many clients. The listening thread’s responsibility is to accept all the requests, and to create more threads for handling these requests. In other words, each time that a new request is accepted by the listening thread, it creates a responding thread, makes the necessary things to enable the client and the new created thread to communicate, and returns to listen, for being able to accept more requests. The things done by the listening thread should be minimal, otherwise it will miss incoming requests. 20 In practice, the listening is done by using a server socket. This is a socket that is used for the listening purpose. See more details about the sockets in the section handling the TCP/IP connection (2.1.4). The implementation of the threads is done by using the MFC class CWinThread. This class wraps the WIN32 API, and handles the threads. For using this class, we had to implement its Run method. This method is the start point of the thread. The listening thread is created upon starting of the server program, and its Run method includes the code that creates the listening socket and a while loop that accepts requests and creates the additional threads needed to perform the work for the clients. The server acts as state-less, which means it doesn’t save data about the clients, and in practice the meaning is that there are constant open connections. For each request, a connection (and thread) is opened, the work, which should be done, is done, the connection is closed and the thread exists. So if we take a situation that many clients are “on the air”, there is no open connection for each one automatically. Once a client initiates an action that requires the server, a connection is established for that purpose and new thread is created in the server. Once the work that the connection and thread were created for is done, the thread exists and the connection is being closed. A state-less mode is good for systems like ours, in which connections are established not too often. All connections are initiated by manual actions, so its clear that they are not established too often, in computers time scale. A good example for a big system that work in state-less mode is the Internet. In a case that connections are not established too often, the overhead of creating new thread and new sockets each time, is not too big, and we can avoid a situation in which we will have many opened connection all the time. In addition, the server implementation is easier as state-less mode. 21 2.1.4 In the Middle (Client – Server communications) 2.1.4.1 Socket handling The connection between the client and server is done by TCP/IP, using sockets. The client side, written in Java, is using the java sockets. As a result of being a client program, it needs only simple sockets. The server side, written in C++, is using the MFC classes Csocket, CsocketFile and Carchieve in order to handle the communication with the clients. In order to enable the connection between the Java sockets to the C++ sockets, we had to define the basic sent packet as ‘byte’ (described in more detail in the special design solutions – chapter 3). The server opens a listening socket, initialized with the server IP and our server program port, and its listening thread waits for requests from the clients on that socket. After receiving a request, the listening thread is opening a new socket for the responding thread, which is created in order to take care of the request by it’s type. Then, the listening thread returns to listen. Each client’s action uses a new socket. This way, the listening thread is listening most of the time and will not miss a request and each request is being handled separately. 2.1.4.2 communication protocols The responding thread, which was created by the listening thread is taking care of the client’s request. it does a switch case on the type of request and operates differently for each request. The flows of requests and their respondings are described here: 1. Get Icons: The client can either enter or not enter a searching string in the GUI and press the get icons button. this will send the server a request with the string as an input. The server will do the followings: If it received a string, it will use it to send the first 50 shapes starting with that string to the client. If the string is empty, it will send the first 50 shapes in the database to the 22 client. The shapes will be sent as .gif icon files with their names, and will appear in the bottom part of the client’s GUI. 2. Get Similar Icons (search): The client can press one of the .gif icons in the GUI, causing its name to appear in the searching string box, and choose an algorithm in the signature type box. Then by pushing the search button, the client sends a comparison request to the server, using the name of the shape he chose as the shape to be compared with the data base, and the algorithm he chose as the comparison method to be used. The server receives the comparison request with the shape’s name and the algorithm’s name. the responding thread calls the compare function and sends the nearest 50 shapes to the client, using the requested algorithm. 3. Get Shape File (show): The client can press one of the .gif icons in the GUI, causing its name to appear in the searching string box, and then push the show 3D shape button. This will send the server a request with the name of the shape as an input. The server receives the request with the .gif file name and converts the name to a .obj file name. Then the server is performing a search for that .obj file name in the data base, and after finding it the server sends it to the client. 23 The client receives the .obj file and operates on it using the Java3D classes, enabling the user to see the shape and move it in all axes. The file will be saved in the directory defined by the user in the GUI as Local Directory. 4. Download Off (downloading a shape from the data base): The client can press one of the .gif icons in the GUI, causing its name to appear in the searching string box, and then push the Download button. This will send the server a request with the name of the shape as an input. The server receives the request with the .gif file name and converts the name to a .off file name. Then the server is performing a search for that .off file name in the data base, and after finding it the server sends it to the client. The client receives the .off file and saves it in the directory defined by the user in the GUI as Local Directory. 5. Upload File Icon (uploading a shape to the data base): The client can push the Upload button, located in the GUI, causing a brows window to pop up. Then choose a .off file from any directory and send the server a request with the name of the file as an input. The server receives the request with the .off file and starts to operate on it: First the .off file is converted to a .obj file, which is saved in the data base (the .off file will be saved too). 24 Then the .off file is converted to a .gif file, which is saved in the data base. And last the .off file is converted to a signature file which is added to the data base. 2.2 Main Classes In this section we will describe the various classes operating in the project. For each class we will describe its general purpose and main members. 2.2.1 The Client Side The client, written in Java, is build of two classes. The first, ClientFrame, has two main purposes. The first is to actually display the user interface and to get the user input. The second is to communicate with the C++ server. So by implementing this two things together, this class gets user requests, activates the appropriate service (from the server) and display to the user what he needs. The second class, ObjLoad, is responsible to the 3D shapes presentation. It loads .obj file and converts its data in a way it will be possible to render it in a Java 3D scene. It also use other Java 3D classes that are needed for the rendering of simple Java 3D scene. ClientFrame Main Methods ClientFrame – The C’tor. As in any Java GUI class, the GUI components are getting connected each other in the c’tor. Each component like buttons and text fields is added to a panel, and all panels are added to the main frame panel. Also in the client, each button adds this class as a listener for sending it the events created by user actions. ActionPerformed – this method appears in the declaration of the ActionListener interface. We must implement it for being able to deal with the GUI events. So as can be understood, when the user makes an action that fires event, as pressing a button, this method is called by the Java environment. So we check at the beginning of the method who is the component that created the event, and we call to another method to do the real work. This is kind of 25 management method – receive event and send it to the place where it should be treated. GetRandomIcons – this method is called by actionPerformed when the Get Icons button is pressed by the user. It takes the relevant data (signature type, icon name) and sends it to the server. It handles the communication with the server for the get icons action. After it receives all the icons, it updates the icons on the user interface. Compare - this method is called by actionPerformed when the Search button is pressed by the user. It takes the relevant data and sends it to the server. It handles the communication with the server for the search action. After it receives all the icons, it updates the icons on the user interface. Show – this method is called by actionPerformed when the Show button is pressed by the user. It takes the relevant data and sends it to the server. It handles the communication with the server for the show action. After it receives the 3D object .obj file from the server, it uses the ObjLoad class to open a new window and display the 3D object. UploadOff - this method is called by actionPerformed when the Upload button is pressed by the user. It handles the communication with the server for the upload action, which, in this case, is to send the .off file to the server. Download - this method is called by actionPerformed when the Download button is pressed by the user. It handles the communication with the server for the download action, which, in this case, is to get the .off file from the server. ObjLoad Main Methods This class inherits from the JFrame class, so it is a frame by itself. ObjLoad – the c’tor. The c’tor is called when an instance of this class is created in the Show method in ClientFrame. The required .obj file is passed to ObjLoad from ClientFrame through this c’tor. Init – this method do most of the work. It do what is needed to handle the frame display, it creates the environment needed around the 3D shape. This class deals with the Java 3D classes used for the lightning effect, for the mouse handling of the shape and so on. 26 CreateSceneGraph – this method is called from init. It creates the scene graph, which means in our case to create the shape object, and put it in the scene graph. By doing so, all the scene graph behavior acts on our shape – the lightning, the mouse handling, etc. . 2.2.2 The Server Side class CListenThread : public CWinThread This class is implementing the listening thread. In its run method is opening a listening socket and listens on it constantly, until a request arrives. For each request, the run method will create a thread (responding thread) and will open a new socket for connecting between the client and the responding thread (using the detach and attach socket operations). class CRespondThread : public CWinThread This class is implementing the responding thread. Its accepting the new socket from the listening thread and communicates with the client in-order to fulfill clients requests. Its operating a switch case on clients requests and acts properly according to the request. The main methods which are implemented in this class are the methods for each request: GetRandomIcons - taking care of the ‘Get Icons’ request. GetSimilarIcons - taking care of the ‘Search’ request. GetShapeFile - taking care of the ‘Show’ request. UploadFileOff - taking care of the ‘Upload’ request. DownloadOff - taking care of the ‘Download’ request. 27 UploadFileIcon – not in use. UploadFileObj – not in use. 3. Special Design Solutions and Conclusions Integration of two environments solution Our client is written in Java and the server in C++. Each one is written in a different language for enjoying some benefits. We had some ready code in the server side, written in C++, so it was obvious that the server will be written in C++. From the other hand, we wanted to use Java 3D for the display of the 3D shapes, because the Java 3D package has useful classes that can get out the most from, what can we do, not an expert 3D programmers. The problem was how to integrate both environments. A direct methods calls from one environment to each other is not an easy thing, and dealing with it can be more difficult than write all software with one language. In a cases like this, the best thing is to find an interface between the environments, that doesn’t require direct methods or functions calls. An example to such an interface is a database (not in our project) where one program write to it data, and the other program read this data and use it. In our project, an interface point like this is the communication layer between the two applications. Each language/environment has a suitable interface for sockets. The good thing of it, that in both sides, when the application read from socket, or write to socket, it doesn’t care who is in the other side. And this was exactly what we wanted!! In this way, we get the most from each side, as described above, and without giving up at other place, because if we used only one language, we would use the sockets in a same way! So by recognition what is the best place to divide our software, we could design the client and the server in a way that gave us the most benefit, with no cost. Communication protocol solution to the two language differences problem Despite of the nice explanation above, we still had some problems in the communication between both sides. 28 First, each socket class has its own special methods. These methods help in transferring data types such as int, double, string etc. . But each language handles the types in other way. Each language read method is compatible to its parallel write method, but not to the other language write method. The solution for this problem was to communicate only with bytes. Byte is well known and handled in both sides. The problem that we had to deal with now was the error returned. Each environment has its own method for returning error. We will not describe here all the problems, but one problem, for example, was that Java use int for being able to return –1. Since byte has 256 possible characters, and each one has a meaning, the result is that when, for example, sending a file from the server, and when file is over and the server send EOF, the java read socket, cant receive any indication from the server that it is EOF. It deals with each byte as it is data. And EOF that the server sends is also a value. It expects to get –1 from the other side as indication for EOF, but in byte it impossible to send this value. The C++ classes dealing with files, know when the file is over. But the Java side, that get a byte each time, know just what it is –1. It is the only value that considered as error. And for this reason, the Java socket classes use int and not byte!!! So our solution was to send a status byte side by side with each data byte. It is not very efficient, but there is no choice. And now, in the Java side, we know, according to our protocol, when to aspect to a status byte, and when to aspect to a data byte. When we get a status byte, we just check if its legal or not. True or false (in a byte data type, off course). And only if its true, we get the data byte, and this time we know for sure that it is really a data byte. And we use it as a data type - one of 256 possible characters. In this way we overcame a problem that was happened because the using socket classes of different environments. Last thing we have to mention is that the problem was because we used high level classes. When using high level class, that wraps many things, you can be sometimes a little limited. If dealing with raw data, you can implement things the same way in both sides. But off course doing all this alone, has many disadvantages, and more than that, when programming in high level language as Java, it is against the rules to do low level things. For this reason, we decided to use the socket classes, and we had our solution to the problem. 29 4. Results Average run time results: Get Icons feature – 5 seconds. Search – 5 seconds. Show – depends on the 3D file size. Between 3 – 10 seconds. Upload & Download – depends on the 3D file size. Up to 10 seconds. Note that these times depend also on the network load. 5. References Java 2 – Teach Yourself in 21 Days, Sams Beginning Java Networking, Wrox Press C++ Programming Language, Bjarne Stroustrup The Java 3D API (by Sun Microsystems) MSDN library The users guide for our project is aimed for users of the client application, since the server will reside in one of the computers in the lab, and the maintenance of it will be done by the project's supervisor. 6. User’s Guide 6.1 About the program 6.1.1 Program description 30 This program is designed to prove 3D comparison algorithms. It is built as a client server application, when the client’s application is written in Java and can operate on any platform. The server resides on one of the computers in the computer programming lab at the Technion, and is ready to accept requests on any given time. 6.1.2 Program features After installing the program, the user can easily perform the following operations: Search for 3D shapes in the database by name/first letters and receive the first 50 matches or just the first 50 shapes in the database. Download shapes from the database. Upload new shapes to the database. Choose a specific shape and present it with the ability of rotating it. Search the database for shapes which are similar to a chosen shape, using various comparing algorithms, and receiving the first 50 matches ordered by their similarity. 6.2 Installation For running a java program from a command line, you should have the Java run time environment installed in your pc. If the program uses the Java 3D package, you should install also the Java 3D run time environment. For doing these installations and running the client program, perform the next steps: Double click on the j2re-1_4_1_01-windows-i586.exe file. This will open a wizard that will install the Java 2, version 1.4.1 for windows platforms. Approve all the steps. Double click on the java3d-1_3-windows-i586-opengl-rt.exe file. This will open a wizard that will install the Java 3D for windows platforms. Approve all the steps. Open a new folder named Proj under your C partition. Make sure this folder contains the next files: ClientFrame.class ObjLoad.class 31 747.gif Enter from the command line into C:\Proj . Type the next command: java ClientFrame This command should start the client program. Note: case sensitive is important. Note: For running the client program on other platforms, the program shouldn’t be compiled again. The only thing you have to do is to install the java and java 3d run time environments on the relevant platform (with the compatible .exe installation files from Sun site). 6.3 Using the GUI After installing the application, run it. The following GUI will appear on your screen: 32 you can start using it! We will go over the possible operations: The Host IP and the Port boxes should contain the details which appear in the ‘ini’ file we supplied you (these are the server’s IP and Port). Keep the ini file in the same directory which you are running the application. Press the Refresh Settings button after any change you make to the Host IP or Port. The Local Directory box should contain your working directory, you need to create this directory before you start and a sub-directory named Icons under it. All files from the database will get to that directory (icons will go into the Icons sub-directory). In the Signature Type box you can choose the algorithm to work with when running comparisons on the database. In the File/Searching string box you can type a full file name or the first letters of a file name and then press the Get Icons button. This will cause a search in the database for shapes with this name/pattern and bring back 50 shapes. When the File/Searching string box is empty, pressing the Get Icons button will bring the first 50 shapes from the database. Shapes which are brought from the database are presented as icons in the low part of the GUI. You can choose any icon of a shape and push the Show button. This will cause a Java 3D presentation of this shape in a new window, where you can rotate the image and look at it from any angle you want. 33 You can upload a shape to the database. Press the Upload button, brows to the .off file on your computer and choose it. This will cause the addition of that shape to the database and then you can make comparisons on it. You can download a shape from the database by choosing it in the GUI (its name will appear in the File/Searching string box) and then push the Download button. This will cause the .off file of the shape to be copied to your Local Directory. You can choose any icon of shape and push the Search button. This will cause a search for similar shapes in the database using the comparison algorithm defined in the Signature Type box. 34