00001 // Copyright (c) 1998-2014 by Tech Soft 3D, Inc. 00002 // 00003 // The information contained herein is confidential and proprietary to Tech Soft 3D, Inc., 00004 // and considered a trade secret as defined under civil and criminal statutes. 00005 // Tech Soft 3D, Inc. shall pursue its civil and criminal remedies in the event of 00006 // unauthorized use or misappropriation of its trade secrets. Use of this information 00007 // by anyone other than authorized employees of Tech Soft 3D, Inc. is granted only under 00008 // a written non-disclosure agreement, expressly prescribing the scope and manner of such use. 00009 00010 #pragma once 00011 00012 #include "hc.h" 00013 #include "HTools.h" 00014 #include "HGlobals.h" 00015 #include "BStream.h" 00016 00017 #include <stdint.h> 00018 #include <functional> 00019 00020 00022 00023 00024 #ifdef _WIN32 00025 # define OOC_API __declspec(dllexport) 00026 #else 00027 # define OOC_API 00028 #endif 00029 00030 00032 00033 00034 class HInputHandlerOptions; 00035 class PointCloudWorld; 00036 class NodeData; 00037 00038 00039 namespace ooc 00040 { 00041 namespace delta 00042 { 00043 namespace on_disk 00044 { 00045 class NodeHandleSerializer; 00046 class NodeHandleDeserializer; 00047 } 00048 } 00049 } 00050 00051 00053 00054 00055 namespace ooc 00056 { 00057 class ReifiedEnv; 00058 00059 00061 class OOC_API Env { 00062 friend class ReifiedEnv; 00063 00064 public: 00069 Env (); 00070 00071 bool operator== (Env const & other) const; 00072 bool operator!= (Env const & other) const; 00073 00074 private: 00075 void * opaque; 00076 uintptr_t key; 00077 }; 00078 00079 00081 class OOC_API Point { 00082 public: 00084 Point () 00085 : x(0.0f) 00086 , y(0.0f) 00087 , z(0.0f) 00088 {} 00089 00096 Point (float x, float y, float z) 00097 : x(x) 00098 , y(y) 00099 , z(z) 00100 {} 00101 00106 Point operator+ (Point const & other) const 00107 { 00108 return Point(x + other.x, y + other.y, z + other.z); 00109 } 00110 00115 Point operator- (Point const & other) const 00116 { 00117 return Point(x - other.x, y - other.y, z - other.z); 00118 } 00119 00124 Point operator* (float scale) const 00125 { 00126 return Point(x * scale, y * scale, z * scale); 00127 } 00128 00133 Point operator/ (float scale) const 00134 { 00135 return Point(x / scale, y / scale, z / scale); 00136 } 00137 00138 public: 00139 float x; 00140 float y; 00141 float z; 00142 }; 00143 00146 class OOC_API NodeHandle { 00147 friend class delta::on_disk::NodeHandleSerializer; 00148 friend class delta::on_disk::NodeHandleDeserializer; 00149 00150 private: 00151 NodeHandle (uint32_t node_file_id, uint32_t node_file_offset); 00152 00153 public: 00155 NodeHandle () {} 00156 00160 NodeHandle (NodeData const & node_data); 00161 00167 static NodeHandle Invalid (); 00168 00169 /* Returns a hash code for a given node handle. Provides a means to hash the 00170 value of an ooc::NodeHandle. 00171 00172 A node handle will always return the same hash value in a given run of a 00173 program. That being said, this function may return different values between 00174 different runs of the program. In other words, the generated hash code is 00175 not persistent between different program executions. 00176 */ 00177 size_t Hash () const; 00178 00184 bool operator== (NodeHandle const & other) const 00185 { 00186 return node_file_id == other.node_file_id && node_file_offset == other.node_file_offset; 00187 } 00188 00194 bool operator!= (NodeHandle const & other) const 00195 { 00196 return !(*this == other); 00197 } 00198 00204 bool operator< (NodeHandle const & other) const 00205 { 00206 if (node_file_id < other.node_file_id) { 00207 return true; 00208 } 00209 if (node_file_id > other.node_file_id) { 00210 return false; 00211 } 00212 return node_file_offset < other.node_file_offset; 00213 } 00214 00215 private: 00216 uint32_t node_file_id; 00217 uint32_t node_file_offset; 00218 }; 00219 00220 00226 OOC_API bool IsRoot (HC_KEY ooc_root); 00227 00235 OOC_API bool GetEnv (HC_KEY ooc_root, Env & out_env); 00236 00242 OOC_API HC_KEY GetRoot (Env env); 00243 00254 OOC_API void Destroy (Env env); 00255 00268 OOC_API void Release (Env env); 00269 00279 OOC_API bool GetNodeHandle (Env env, HC_KEY node_segment_key, NodeHandle & out_node_handle); 00280 00287 OOC_API HC_KEY GetSegmentKey (Env env, NodeHandle const & node_handle); 00288 00298 OOC_API HC_KEY GetShellKey (Env env, NodeHandle const & node_handle); 00299 00310 OOC_API bool PollNodesLoadingOrHaveBeenLoaded (Env env); 00311 00318 OOC_API int Configure (char const * in, char * out); 00319 00320 00321 namespace delta 00322 { 00323 class OOC_API SyncToken; 00324 00326 enum SyncResult { 00327 SyncResult_Success, 00328 }; 00329 00344 OOC_API SyncResult SynchronizeWith (Env, std::function<void(SyncToken const &)>); 00345 00346 class OOC_API InternalSynchronizer { 00347 friend SyncResult SynchronizeWith (Env, std::function<void(SyncToken const &)>); 00348 00349 private: 00350 InternalSynchronizer (Env env); 00351 ~InternalSynchronizer (); 00352 00353 PointCloudWorld & GetWorld () const; 00354 00355 private: 00356 void operator= (InternalSynchronizer const &); 00357 00358 private: 00359 PointCloudWorld & pcw; 00360 }; 00361 00362 enum ModifyResult { 00363 ModifyResult_Success, 00364 ModifyResult_Error_Unknown_Failure, 00365 ModifyResult_Error_Internal_Failure, 00366 ModifyResult_Error_Could_Not_Find_Node, 00367 ModifyResult_Error_Input_Indices_Are_Not_Strictly_Increasing, 00368 ModifyResult_Error_Illegal_Input_Indices, 00369 ModifyResult_Error_Corrupt_Node, 00370 ModifyResult_Error_File_System_Failure, 00371 }; 00372 00381 OOC_API ModifyResult DeleteNode (SyncToken const & sync_token, NodeHandle const & node_handle); 00382 00401 OOC_API ModifyResult DeleteSpecificPoints (SyncToken const & sync_token, NodeHandle const & node_handle, int32_t const point_indices[], size_t count); 00402 00404 enum OptimizeResult { 00405 OptimizeResult_Success, 00406 OptimizeResult_Error_Unknown_Failure, 00407 }; 00408 00410 class OOC_API OptimizeConfig { 00411 public: 00412 // Currently there are no config options. 00413 00414 public: 00415 bool operator== (OptimizeConfig const & other) const; 00416 bool operator!= (OptimizeConfig const & other) const; 00417 }; 00418 00419 OOC_API OptimizeResult OptimizeDeltas (SyncToken const & sync_token, OptimizeConfig const & config); 00420 00427 class OOC_API SyncToken { 00428 friend SyncResult SynchronizeWith (Env, std::function<void(SyncToken const &)>); 00429 friend ModifyResult DeleteNode (SyncToken const &, NodeHandle const &); 00430 friend ModifyResult DeleteSpecificPoints (SyncToken const &, NodeHandle const &, int32_t const[], size_t); 00431 00443 friend OptimizeResult OptimizeDeltas (SyncToken const & sync_token, OptimizeConfig const & config); 00444 00445 public: 00446 Env GetEnv () const; 00447 00448 private: 00449 SyncToken (Env env, PointCloudWorld & pcw); 00450 PointCloudWorld & GetWorld () const; 00451 00452 private: 00453 SyncToken (SyncToken const &); // disable 00454 SyncToken (SyncToken &&); // disable 00455 void operator= (SyncToken const &); // disable 00456 void operator= (SyncToken &&); // disable 00457 void operator& () const; // disable 00458 00459 private: 00460 Env env; 00461 PointCloudWorld & pcw; 00462 }; 00463 00464 00465 // NOTE: Because std::function is in the API, this function must be defined in the header to avoid ABI problems. 00466 inline OOC_API SyncResult SynchronizeWith (Env env, std::function<void(SyncToken const &)> func) 00467 { 00468 InternalSynchronizer synchronizer(env); 00469 PointCloudWorld & pcw = synchronizer.GetWorld(); 00470 SyncToken const sync_token(env, pcw); 00471 func(sync_token); 00472 return SyncResult_Success; 00473 } 00474 } 00475 00476 00477 namespace io 00478 { 00480 enum IOResult { 00481 IOResult_Success, 00482 IOResult_Error_Unknown_Failure, 00483 IOResult_Error_No_HBaseView, 00484 IOResult_Error_Cyclic_File_Dependencies, 00485 IOResult_Error_Serialization_Failure, 00486 IOResult_Error_Deserialization_Failure, 00487 IOResult_Error_Illegal_File_Name, 00488 IOResult_Error_File_System_Failure, 00489 IOResult_Error_OOC_Root_Already_Exists, 00490 IOResult_Error_Invalid_Buffer, 00491 }; 00492 00509 OOC_API IOResult FileInputByKey (wchar_t const * file_name, HC_KEY segment_key, HInputHandlerOptions const & options); 00510 OOC_API IOResult FileInputByKey (char * buffer, int buffer_size, wchar_t const * file_name, HC_KEY segment_key, HInputHandlerOptions const & options); 00511 00540 OOC_API IOResult CommitDeltasToFile (Env env, H_UTF8 * out_generated_file_name = 0); 00541 OOC_API IOResult CommitDeltasToFile (char * buffer, int buffer_size, Env env, H_UTF8 * out_generated_file_name = 0); 00542 00546 OOC_API IOResult CommitDeltasToFile (Env env, H_UTF8 const & file_name); 00547 OOC_API IOResult CommitDeltasToFile (char * buffer, int buffer_size, Env env, H_UTF8 const & file_name); 00548 00558 OOC_API bool HasUncommittedDeltas (Env env); 00559 } 00560 00561 00562 namespace query 00563 { 00564 class QueryIterator; 00565 00567 enum Storage { 00568 Storage_Memory, 00569 Storage_Disk, 00570 }; 00571 00573 class OOC_API Filter { 00574 friend class QueryIterator; 00575 00576 public: 00577 Filter () {} 00578 virtual ~Filter () {} 00579 00584 virtual bool RejectPointsInMemory () = 0; 00585 00590 virtual bool RejectPointsOnDisk () = 0; 00591 00597 virtual bool RejectNode (NodeHandle const & node_handle) = 0; 00598 00605 virtual bool RejectBounding (Point const & min_bound, Point const & max_bound) = 0; 00606 00612 virtual bool AcceptPoint (Point const & point, size_t point_index) = 0; 00613 }; 00614 00617 class OOC_API QueryResult { 00618 friend class QueryIterator; 00619 00620 private: 00621 QueryResult (); 00622 00623 public: 00628 NodeHandle const & GetNodeHandle () const; 00629 00634 Point const & GetNodePoint () const; 00635 00640 size_t GetNodePointIndex () const; 00641 00646 Storage GetStorage () const; 00647 00648 private: 00649 NodeHandle node_handle; 00650 Point node_point; 00651 size_t node_point_index; 00652 Storage storage; 00653 }; 00654 00662 OOC_API QueryIterator QueryPoints (Env env, Filter & filter); 00663 00670 OOC_API int PointCount (Env env, NodeHandle const & handle); 00671 00673 class OOC_API QueryIterator { 00674 friend QueryIterator QueryPoints (Env, Filter &); 00675 00676 public: 00677 enum Status { 00678 Status_Alive, 00679 Status_Dead, 00680 Status_Error_Unknown_Failure, 00681 Status_Error_File_System_Failure, 00682 Status_Error_Deserialization_Failure, 00683 Status_Error_Could_Not_Find_Node, 00684 Status_Error_Corrupt_Node, 00685 }; 00686 00687 private: 00688 QueryIterator (Filter & filter, Status status); 00689 QueryIterator (Env env, Filter & filter, NodeHandle const & node_handle); 00690 00691 public: 00695 QueryIterator (); 00696 00700 QueryIterator (QueryIterator && other); 00701 ~QueryIterator (); 00702 00707 QueryResult const & operator* () const; 00708 00713 QueryResult const * operator-> () const; 00714 00719 Status GetStatus () const; 00720 00723 void Advance (); 00724 00725 private: 00726 void InvalidateWith (Status status); 00727 00728 enum HookStatus { 00729 HookStatus_Success_Hooked, 00730 HookStatus_Success_Skipped, 00731 HookStatus_Error_Unknown_Failure, 00732 HookStatus_Error_File_System_Failure, 00733 HookStatus_Error_Deserialization_Failure, 00734 HookStatus_Error_Corrupt_Node, 00735 }; 00736 00737 void Hook (); 00738 HookStatus HookNode (NodeHandle const & node_handle, HC_KEY const node_segment_key); 00739 HookStatus HookNodePoints (HC_KEY const node_segment_key); 00740 HookStatus HookNodePointsAgainstShell (HC_KEY const node_shell_key); 00741 HookStatus HookNodePointsAgainstDisk (HC_KEY const node_segment_key); 00742 00743 private: 00744 QueryIterator (QueryIterator const &); // disable 00745 void operator= (QueryIterator const &); // disable 00746 void operator= (QueryIterator &&); // disable 00747 00748 private: 00749 void * typeless_pending_node_keys; 00750 void * typeless_point_buffer; 00751 size_t point_buffer_idx; 00752 Filter & filter; 00753 Env const env; 00754 QueryResult query_result; 00755 Status status; 00756 }; 00757 } 00758 00759 00760 namespace preprocess 00761 { 00762 enum PreprocessStatus { 00763 PreprocessStatus_Success, 00764 PreprocessStatus_Unknown_Failure, 00765 PreprocessStatus_Setup_Failure, 00766 PreprocessStatus_First_Pass_Failure, 00767 PreprocessStatus_Second_Pass_Failure, 00768 PreprocessStatus_Third_Pass_Failure, 00769 }; 00770 00771 00772 class OOC_API Preprocessor { 00773 public: 00774 Preprocessor (wchar_t const * output_file_name); 00775 ~Preprocessor (); 00776 00777 PreprocessStatus Run (); 00778 00779 void SetLogFile (wchar_t const * log_file); 00780 void AddPointCloudFile (wchar_t const * point_cloud_file); 00781 void SetMaxShellSize (int shell_size); 00782 void SetMaxMemoryUsage (size_t max_memory_usage); 00783 void SetSubSamplePercentage (double percentage); 00784 void SetCullingBoundingBox (Point const & min, Point const & max); 00785 void OverwriteExistingFiles (bool overwrite); 00786 00787 private: 00788 void * opaque_point_cloud; 00789 }; 00790 } 00791 } 00792 00793 00794 00795 00796 00797 00798 00799 00800 00801 00802 00803 00804 00805 00806