The header file for the QisMBoolFiles extension Library


#ifndef __COPYRIGHT_ARTWORK_CONVERSION_QISMBOOLFILES_H
#define __COPYRIGHT_ARTWORK_CONVERSION_QISMBOOLFILES_H
#ifdef __cplusplus

#include <stdlib.h>
#include "qismextension.h"

namespace NsQisMLib {
class QisMFile;
}

namespace NsQisMBoolFiles {

/*******************************************************************************
QisMBoolFiles Flags
*******************************************************************************/
struct QisMBoolFilesFlags
{
  /*****************************************************************************
  Operation codes 
  *****************************************************************************/
  enum Operation {  
     DO_OR = 1 /* Agrregate polygons of file1 and file2 without unionizing */
    ,DO_UNION = 2 /* Unionize polygons of file1 and file2 */
    ,DO_INTERSECTION = 3 /* Compute intersection of polygons between file1 and 
                            file2 */
    ,DO_DIFFERENCE = 4 /* Compute difference file1 - file2 */
    ,DO_XOR = 5 /* Compute XOR file1 vs file2 */
  };
};

/*******************************************************************************
QisMBoolFiles Error Codes
*******************************************************************************/
struct QisMBoolFilesError
{
  /*****************************************************************************
  From QisMBoolFiles::Booleanize_two_files
  *****************************************************************************/
  enum Booleanize_two_files_codes {
     BTF_INV_FILEDB = -1 /* Invalid file handle(s) */
    ,BTF_INV_FILE_DBU = -2 /* File1 grid,units (<grid>,<units>) do not match 
                              File2 (<grid>,<units>) */
    ,BTF_PROC_INIT = -3 /* Initialization failed for processor <id>, <why> */
    ,BTF_OPERATION = -4 /* Thread error: <msg> */
    ,BTF_LICENSE = -5 /* Licensing failed, <why> */
  };
};

/*******************************************************************************
Object to store a set of windows
*******************************************************************************/
class QisMBoolFilesWindows
{
public:
  /*****************************************************************************
  Get implementation name and version
  *****************************************************************************/
  virtual const char* Object_name() const = 0;
 
  /*****************************************************************************
  Cast a QisMBoolFilesWindows* to any other version (derived from it). Future
  versions would have names QisMBoolFilesWindowsV2, QisMBoolFilesWindowsV3 ...
  where V<number> represents the version number. QisMBoolFilesWindows is V1

  Alternative to using dynamic_cast
  *****************************************************************************/
  virtual void* Cast_this(const int version) = 0;
  virtual const void* Cast_this(const int version) const = 0;
  virtual int Latest_version() const = 0;

  /*****************************************************************************
  Clear all the windows
  *****************************************************************************/
  virtual void Reset() = 0;

  /*****************************************************************************
  Add a new window to this set
  ----------------------------------------------------------------------------*/
  virtual bool Add(
    const char* base_name, const double llx, const double lly, 
    const double urx, const double ury, const double grid = 0.0
    ) = 0;
  /*----------------------------------------------------------------------------
  PARAMETERS
  + base_name : Name to identify this window
  + llx, lly, urx, ury : Min-max X,Y co-ordinates of the window extents in file
                         units
  + grid : Smallest measurable distance in file units. urx > (llx + grid), 
           ury > (lly + grid)
  ------------------------------------------------------------------------------
  RETURN
  + Success : true
  + Failure : false, invalid window extents
  *****************************************************************************/

  /*****************************************************************************
  Randomize the order of the windows in this set
  *****************************************************************************/
  virtual void Random_shuffle() = 0;

  /*****************************************************************************
  Get the number of windows in this set
  *****************************************************************************/  
  virtual size_t Count() const = 0;

  /*****************************************************************************
  Get a specific window from this set
  ----------------------------------------------------------------------------*/  
  virtual const char* Get(
    const int index, double& llx, double& lly, double& urx, double& ury
    ) const = 0;
  /*----------------------------------------------------------------------------
  PARAMETERS
  + index : Window position >= 0 and < QisMBoolFilesWindows::Count()
  + llx, lly, urx, ury : Buffer to get the min-max X,Y co-ordinates of the 
                         window extents in file units
  *****************************************************************************/
};
 
/*******************************************************************************
Object to store options for boolean ops between two files
*******************************************************************************/ 
class QisMBoolFilesParams
{
public:
  /*****************************************************************************
  Get implementation name and version
  *****************************************************************************/
  virtual const char* Object_name() const = 0;

  /*****************************************************************************
  Cast a QisMBoolFilesParams* to any other version (derived from it). Future
  versions would have names QisMBoolFilesParamsV2, QisMBoolFilesParamsV3 ...
  where V<number> represents the version number. QisMBoolFilesParams is V1

  Alternative to using dynamic_cast
  *****************************************************************************/
  virtual void* Cast_this(const int version) = 0;
  virtual const void* Cast_this(const int version) const = 0;
  virtual int Latest_version() const = 0;

  /*****************************************************************************
  Reset options to default values
  *****************************************************************************/  
  virtual void Reset() = 0;

  /*****************************************************************************
  Set/Get the operation code. Default: QisMBoolFilesFlags::DO_OR 
  *****************************************************************************/  
  virtual void Operation(const QisMBoolFilesFlags::Operation op) = 0;
  virtual QisMBoolFilesFlags::Operation Operation() const = 0;
  
  /*****************************************************************************
  Set/Get window clipping to ON (true)/OFF (false). Default: ON
  *****************************************************************************/  
  virtual void Clip(const bool onOff) = 0;
  virtual bool Clip() const = 0;
  
  /*****************************************************************************
  Set/Get the number of windows to be processed in parallel (n_window_threads)
  and the number of threads per window for boolean operations 
  (n_threads_per_window). Default: 0 (Auto-set), 1
  *****************************************************************************/  
  virtual void Threads(
    const int n_window_threads, const int n_threads_per_window
    ) = 0;
  virtual int Window_threads() const = 0;
  virtual int Threads_per_window() const = 0;
  
  /*****************************************************************************
  Set/Get sliver value (smallest acceptable size in file units for output 
  polygons). Default: 0.0 (No sliver removal)
  *****************************************************************************/  
  virtual void Sliver(const double value) = 0;
  virtual double Sliver() const = 0;

  /*****************************************************************************
  Set/Get max. number of vertices per polygon ( >= 4 and <= 8190)
  Default: 8190
  *****************************************************************************/  
  virtual void Max_output_vertices(const int n) = 0;
  virtual int Max_output_vertices() const = 0;

  /*****************************************************************************
  Turn Dynamic-windowing ON/OFF. Default: 0 (OFF)
  When n_vert_per_win > 0, every window that has more than n_vert_per_win*2 
  vertices will be split into four quads and re-processed. This can lead to 
  siginificant performance improvement. This should not be used if window 
  extents of the output needs to be same as the input
  *****************************************************************************/  
  virtual void Dynamic_windows(const int n_vert_per_win) = 0;
  virtual int Dynamic_windows() const = 0;
};

class QisMBoolFilesClient
{
public:
  /*****************************************************************************
  To be implemented by the client handler as specified 

  Cast a QisMBoolFilesClient* to any other version (derived from it). Future
  versions would have names QisMBoolFilesClientV2, QisMBoolFilesClientV3 ...
  where V<number> represents the version number. QisMBoolFilesClient is V1

  Alternative to using dynamic_cast
  *****************************************************************************/
  virtual void* QisMBoolFilesClient_cast(const int version) = 0;
  /* PLEASE COPY THIS BODY IN YOUR HANDLER {
    switch(version) {
      case 0: return this; 
      case 1: return dynamic_cast<QisMBoolFilesClient*>(this);
    }
    return 0;
  } */
  virtual const void* QisMBoolFilesClient_cast(const int version) const = 0;
  /* PLEASE COPY THIS BODY IN YOUR HANDLER {
    switch(version) {
      case 0: return this; 
      case 1: return dynamic_cast<const QisMBoolFilesClient*>(this);
    }
    return 0;
  } */
  virtual int QisMBoolFilesClient_latest_version() const = 0;
  /* PLEASE COPY THIS BODY IN YOUR HANDLER {
    return 1;
  } */

  /*****************************************************************************
  Intercept an informational message from QisMBoolFiles
  *****************************************************************************/ 
  virtual void On_qismboolfiles_message_mt(
    const char* pre, const char* msg, const char* post
    ) {}

  /*****************************************************************************
  Intercept a warning message from QisMBoolFiles. Return non-zero to 
  interrupt execution
  *****************************************************************************/ 
  virtual int On_qismboolfiles_warning_mt(
    const char* pre, const char* msg, const char* post
    ) { return 0; }

  /*****************************************************************************
  Notification that a specific window has been processed
  ----------------------------------------------------------------------------*/ 
  virtual int On_qismboolfiles_window_mt(
    const char* window_name, const double* extents, 
    const int* const* xy1, const int* nv1, const int n1,
    const int* const* xy2, const int* nv2, const int n2,
    const int* const* xy0, const int* nv0, const int n0,
    const double grid
    ) { return 0; }
  /*----------------------------------------------------------------------------
  PARAMETERS
  + window_name : Name of the window in question 
  + extents : FOUR doubles representing min-max X,Y co-ordinates of the 
     extents of the window in question
  + n1, n2, n0 : Number of polygons in input set 1, 2 and output. This is also 
     the size of (xy1, xy2, xy0) and (nv1, nv2, nv0) arrays
  + nv1, nv2, nv0 : Array of no. vertices for each polygon in the input set 1, 2
     and output respectively
  + xy1, xy2, xy0 : Array of arrays of x,y co-ordinates for each polygon in the 
     input set 1, 2 and output respectively
  ------------------------------------------------------------------------------
  RETURN
  + zero to continue execution
  + non-zero to interrupt execution (will result in an error message:
    Client interrupt [code <value>])
  ------------------------------------------------------------------------------
  DETAILS
  + A set of polygons is represented by THREE parameters
    * n is the number of polygons in this set
    * nv is the array of number of vertices per polygon in this set. For 
      0 <= i < n, nv[i] represents the number of vertices for polygon i
    * xy is the array of arrays, one per polygon containing the x,y co-ordinates
      of that polygon. For 0 <= i < n; xy[i] represents a single polygon i and 
      contains nv[i] x,y pairs or nv[i]*2 integers  
  + **CAUTION** This notification can originate from multiple threads 
    simultaneously. It is the responsibility of the client to ensure that any 
    operations performed inside this notification is done in a thread-safe 
    manner
  *****************************************************************************/
};

#define QISMEXTENSION_BOOLFILES "QisMBoolFiles"
#define QISMCODE_BOOLFILES 11071

class QisMBoolFiles: public NsQisMLib::QisMExtensionAPI
{
public:
  /*****************************************************************************
  Cast a QisMBoolFiles* to any other version (derived from it). Future
  versions would have names QisMBoolFilesV2, QisMBoolFilesV3 ...
  where V<number> represents the version number. QisMBoolFiles is V1

  Alternative to using dynamic_cast
  *****************************************************************************/
  virtual void* Cast_this(const int version) = 0;
  virtual const void* Cast_this(const int version) const = 0;
  virtual int Latest_version() const = 0;

  /*****************************************************************************
  Get message/code for the last error condition
  *****************************************************************************/
  virtual const char* Get_last_error_msg() const = 0;
  virtual int Get_last_error_code() const = 0;

  /*****************************************************************************
  Create/Destroy objects of specific classes
  ----------------------------------------------------------------------------*/ 
  virtual void* New_object(const char* class_name) = 0;
  virtual void Delete_object(const char* class_name, void* handle) = 0;
  /*----------------------------------------------------------------------------
  PARAMETERS
  + class_name : Name of the class whose object is to be created/destroyed. 
    Valid names are:
    * QisMBoolFilesWindows
    * QisMBoolFilesParams
  + handle: Handle to the object to be destroyed
  ------------------------------------------------------------------------------
  RETURN
  + Success : non-NULL pointer to a new object 
  + Failure : NULL (Invalid/Unrecognized class name)
  ------------------------------------------------------------------------------
  DETAILS
  + Each object created by this method MUST be type-casted to that specific
    class only and MUST be eventually destroyed using Delete_object(..) to
    avoid memory/resource leak
  *****************************************************************************/
  
  /*****************************************************************************
  Perform boolean operation between sets of polygons of two files
  ----------------------------------------------------------------------------*/ 
  virtual bool Booleanize_two_files(
    NsQisMLib::QisMFile* file_1, const char* cell_1, const char* layers_1, 
    NsQisMLib::QisMFile* file_2, const char* cell_2, const char* layers_2,
    const QisMBoolFilesWindows* window_set, const QisMBoolFilesParams* options,
    QisMBoolFilesClient* client, const int argc = 0,
    const char* const* argt = 0, const void* const* argv = 0
    ) = 0;
  /*----------------------------------------------------------------------------
  PARAMETERS
  + file_1, file_2 : Handle to the two QisMFile databases already loaded using
    QisMLib::Load_file
  + cell_1, cell_2 : Names of the view cells for both files. If cell_1 is 
    empty/null, the default top cell is used. If cell_2 is empty/null, it is 
    set to cell_1
  + layers_1, layers_2 : Comma-separated list of layers from each file to be
    used. If layers_1 is empty/null/"ALL", all layers of file_1 are used. If
    layers_2 is empty/null, layers_2 is set to layers_1. If layers_2 is ALL,
    all layers of file_2 are used
  + window_set : Set of windows to be processed. If this set is empty/null, 
    the extents of the first file's view cell are used as the only window
  + options : Various options to for processing these windows. If null, 
    default values are used
  + client : Pointer to an object that will handle various notifications while
    the operation is in progress. The handler MUST implement the 
    QisMBoolFilesClient interface and override relevant notification methods
  + argc, argt, argv : Misc. options reserved for internal use
  ------------------------------------------------------------------------------
  RETURN
  + Success : non-NULL pointer to a new object 
  + Failure : NULL (Invalid/Unrecognized class name)
  ------------------------------------------------------------------------------
  DETAILS
  + This method creates 'QisMBoolFilesParams::Window_threads()' processor 
    threads which simultaneously extracted polygons for a specific window 
    from both files and then performs boolean operations between those polygons.
  + The resulting data set is served up to the client in form of the 
    QisMBoolFilesClient::On_qismboolfiles_window_mt notification
  + Each processor/window thread fetches a new window from a shared queue. The 
    function returns when there is no more window to be processed
  *****************************************************************************/
};

}

#endif /* __cplusplus */
#endif /* __COPYRIGHT_ARTWORK_CONVERSION_QISMBOOLFILES_H */

/*******************************************************************************
v1.0 (2017-11-09)
--------------------------------------------------------------------------------
+ First cut
*******************************************************************************/