aboutsummaryrefslogtreecommitdiff
path: root/project/src/lib-kcl.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--project/src/lib-kcl.h1221
1 files changed, 1221 insertions, 0 deletions
diff --git a/project/src/lib-kcl.h b/project/src/lib-kcl.h
new file mode 100644
index 0000000..9a73043
--- /dev/null
+++ b/project/src/lib-kcl.h
@@ -0,0 +1,1221 @@
+
+/***************************************************************************
+ * _______ _______ _______ *
+ * | ___ |____ | ___ | *
+ * | | |_| / /| | |_| *
+ * | |_____ / / | |_____ *
+ * |_____ | / / |_____ | *
+ * _ | | / / _ | | *
+ * | |___| |/ /____| |___| | *
+ * |_______|_______|_______| *
+ * *
+ * Wiimms SZS Tools *
+ * https://szs.wiimm.de/ *
+ * *
+ ***************************************************************************
+ * *
+ * This file is part of the SZS project. *
+ * Visit https://szs.wiimm.de/ for project details and sources. *
+ * *
+ * Copyright (c) 2011-2020 by Dirk Clemens <wiimm@wiimm.de> *
+ * *
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
+ * *
+ ***************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef SZS_LIB_KCL_H
+#define SZS_LIB_KCL_H 1
+
+#include "lib-std.h"
+#include "db-kcl.h"
+#include "lib-image.h"
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// definitions ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef TEST // [[cube]]
+ #define SUPPORT_KCL_CUBE 1
+ #define SUPPORT_KCL_XTRIDATA 0 // 0=off, 1=extra
+ #define SUPPORT_KCL_DELTA 0 // 0|1
+#else
+ #define SUPPORT_KCL_CUBE 0
+ #define SUPPORT_KCL_XTRIDATA 0
+ #define SUPPORT_KCL_DELTA 0
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+#define KCL_TEXT_MAGIC "#KCL"
+#define KCL_TEXT_MAGIC_NUM 0x234b434c
+
+#define KCL_SIGNATURE "WiimmSZS"
+
+#define KCL_MTL_EXT ".mtl"
+#define KCL_FLAG_FILE1 "\1P/\1N\1T"
+#define KCL_FLAG_FILE2 "\1P/\1F\1T"
+#define KCL_FLAG_EXT ".flag"
+
+#define N_KCL_SECT 4
+
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_analyze_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_analyze_t]]
+
+typedef struct kcl_analyze_t
+{
+ valid_t valid; // valid status
+ u16 order_value; // digits 1, 2, 3, 4 as dec to reflect order
+ bool order_ok; // true: regular order (order_value==1234)
+ u32 head_size; // size of head
+ u32 file_size; // not NULL: size of file
+ u32 off[N_KCL_SECT]; // offsets of KCL sections
+ u32 size[N_KCL_SECT]; // max size of KCL sections (U32_MAX=unknown)
+ u32 n[N_KCL_SECT]; // number of KCL entries based on 'size'
+}
+kcl_analyze_t;
+
+ccp GetValidInfoKCL ( kcl_analyze_t * ka );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_head_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct kcl_head_t
+{
+ /*0x00*/ u32 sect_off[N_KCL_SECT]; // offset of the 4 sections
+ /*0x10*/ float32 unknown_0x10;
+ /*0x14*/ float32 min_octree[3]; // minimum values
+ /*0x20*/ u32 mask[3]; // masks for spatial index
+ /*0x2c*/ u32 coord_rshift; // right shift for all coord
+ /*0x30*/ u32 y_lshift; // left shift for y values
+ /*0x34*/ u32 z_lshift; // left shift for z values
+ /*0x38*/ float32 unknown_0x38;
+ /*0x3c*/
+}
+__attribute__ ((packed)) kcl_head_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_triangle_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+typedef struct kcl_triangle_t
+{
+ /*0x00*/ float32 length; //
+ /*0x04*/ u16 idx_vertex; //
+ /*0x06*/ u16 idx_normal[4]; //
+ /*0x0e*/ u16 flag; // KCL flag (includes the type)
+ /*0x10*/
+}
+__attribute__ ((packed)) kcl_triangle_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_tridata_status_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_tridata_status_t]]
+
+typedef enum kcl_tridata_status_t
+{
+ TD_INVALID_NORM = 0x01, // 'length' & 'normal' are invalid
+ TD_INVALID = 0x02, // invalid data
+ TD_FIXED_PT = 0x04, // triangle was fixed/repaired
+ TD_UNUSED = 0x08, // triangle not used in octree
+ TD_REMOVED = 0x10, // triangle is marked as 'removed'
+ TD_ADDED = 0x20, // triangle was added
+ TD_MARK = 0x40, // temporary marker for calculations
+
+ TDX_ORIG_PT = 0x1000, // original 'pt' valid
+ TDX_ORIG_NORM = 0x2000, // original 'length' & 'normal' valid
+
+} kcl_tridata_status_t;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_tridata*_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_tridata_flt_t]] [[xtridata]]
+
+typedef struct kcl_tridata_flt_t
+{
+ double3 pt[3]; // 3 points
+ float length; // length
+ float3 normal[4]; // 4 normal values
+}
+__attribute__ ((packed)) kcl_tridata_flt_t;
+
+//-----------------------------------------------------------------------------
+// [[kcl_tridata_dbl_t]] [[xtridata]]
+
+typedef struct kcl_tridata_dbl_t
+{
+ double3 pt[3]; // 3 points
+ double length; // length
+ double3 normal[4]; // 4 normal values
+}
+__attribute__ ((packed)) kcl_tridata_dbl_t;
+
+//-----------------------------------------------------------------------------
+// [[kcl_tridata0_t]]
+
+typedef struct kcl_tridata0_t
+{
+ double3 pt[3]; // 3 points
+ float length; // length -> TD_INVALID_NORM
+ float3 normal[4]; // 4 normal values -> TD_INVALID_NORM
+
+ #if SUPPORT_KCL_DELTA
+ float delta_min; // minimal distance of 3 points
+ float delta_max; // maximal distance of 3 points
+ #endif
+
+ u16 status; // bit field: kcl_tridata_status_t
+ u16 in_flag; // original flag of input
+ u32 cur_flag; // current flag
+
+} kcl_tridata0_t;
+
+//-----------------------------------------------------------------------------
+// [[kcl_tridata1_t]] [[xtridata]]
+
+typedef struct kcl_tridata1_t
+{
+ double3 pt[3]; // 3 points
+ float length; // length -> TD_INVALID_NORM
+ float3 normal[4]; // 4 normal values -> TD_INVALID_NORM
+
+ #if SUPPORT_KCL_DELTA
+ float delta_min; // minimal distance of 3 points
+ float delta_max; // maximal distance of 3 points
+ #endif
+
+ u16 status; // bit field: kcl_tridata_status_t
+ u16 in_flag; // original flag of input
+ u32 cur_flag; // current flag
+
+ //-- extra data: input
+
+ kcl_tridata_dbl_t dbl; // parts invalid on TD_INVALID_NORM
+ kcl_tridata_dbl_t orig; // valid on TDX_ORIG_PT, TDX_ORIG_NORM
+
+} kcl_tridata1_t;
+
+//-----------------------------------------------------------------------------
+// [[kcl_tridata_t]] [[xtridata]]
+
+#if SUPPORT_KCL_XTRIDATA > 0
+ typedef kcl_tridata1_t kcl_tridata_t;
+#else
+ typedef kcl_tridata0_t kcl_tridata_t;
+#endif
+
+//-----------------------------------------------------------------------------
+
+void CopyTriData_F2D ( kcl_tridata_dbl_t *dest, const kcl_tridata_flt_t *src );
+void CopyTriData_D2F ( kcl_tridata_flt_t *dest, const kcl_tridata_dbl_t *src );
+
+static inline void CopyTriData_T2D ( kcl_tridata_dbl_t *dest, const kcl_tridata_t *src )
+ { CopyTriData_F2D(dest,(const kcl_tridata_flt_t*)src); }
+static inline void CopyTriData_D2T ( kcl_tridata_t *dest, const kcl_tridata_dbl_t *src )
+ { CopyTriData_D2F((kcl_tridata_flt_t*)dest,src); }
+
+static inline void CopyTriData_T2F ( kcl_tridata_flt_t *dest, const kcl_tridata_t *src )
+ { memcpy(dest,src,sizeof(*dest)); }
+static inline void CopyTriData_F2T ( kcl_tridata_t *dest, const kcl_tridata_flt_t *src )
+ { memcpy(dest,src,sizeof(*src)); }
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_mode_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_mode_t]]
+
+typedef enum kcl_mode_t
+{
+ //--- general options
+
+ KCLMD_FAST = 0x00000001, // fast mode: don't find duplicates
+ KCLMD_ROUND = 0x00000002, // round normals toward zero
+ KCLMD_NORMALS = 0x00000004, // print normals into OBJ
+ KCLMD_MTL = 0x00000008, // print materials on OBJ export
+ KCLMD_WIIMM = 0x00000010, // print materials, use "wiimm.mtl" as file
+ KCLMD_TRIANGLES = 0x00000020, // export as triangle list
+ KCLMD_OUT_SWAP = 0x00000040, // swap points #2 and #3 while generating OBJ
+
+ KCLMD_USEMTL = 0x00000080, // use 'usemtl' for groups if reading OBJ
+ KCLMD_G = 0x00000100, // use 'g' for groups if reading OBJ
+ KCLMD_CLIP = 0x00000200, // enable clip function => const 'KCL_CLIP'
+ KCLMD_IN_SWAP = 0x00000400, // swap points #2 and #3 while reading OBJ
+ KCLMD_AUTO = 0x00000800, // enable auto swap while reading OBJ
+
+ KCLMD_CENTER = 0x00001000, // center world in cube area on octree creation
+ KCLMD_ADD_ROAD = 0x00002000, // for 'kcl_ref' only: Add DMD_ROADOBJ objects
+
+ KCLMD_HEX4 = 0x00004000, // enable flag _XXXX detection in group names
+ KCLMD_HEX23 = 0x00008000, // enable flag _XX_XXX detection in group names
+ KCLMD_M_HEX = KCLMD_HEX4
+ | KCLMD_HEX23,
+
+ KCLMD_CUBE = 0x00010000, // use cubes around triangles for octree calculation
+
+ KCLMD_SMALL = 0x01000000, // aggressive preset to get a smaller kcl
+ KCLMD_CHARY = 0x02000000, // chary preset, Nintendo like
+ KCLMD_DRAW = 0x04000000, // preset for drawing
+ KCLMD_M_PRESET = KCLMD_SMALL
+ | KCLMD_CHARY
+ | KCLMD_DRAW,
+
+ KCLMD_M_GENERAL = KCLMD_FAST
+ | KCLMD_ROUND
+ | KCLMD_NORMALS
+ | KCLMD_MTL
+ | KCLMD_WIIMM
+ | KCLMD_TRIANGLES
+ | KCLMD_OUT_SWAP
+ | KCLMD_G
+ | KCLMD_USEMTL
+ | KCLMD_CLIP
+ | KCLMD_IN_SWAP
+ | KCLMD_AUTO
+ | KCLMD_CENTER
+ | KCLMD_M_HEX
+ | KCLMD_CUBE
+ | KCLMD_M_PRESET,
+
+
+ //--- KCL patching options
+
+ KCLMD_DROP_AUTO = 0x10000000, // enable DROP auto mode
+ KCLMD_DROP_UNUSED = 0x20000000, // remove unreferenced triangles
+ KCLMD_DROP_FIXED = 0x40000000, // remove fixed triangles
+ KCLMD_DROP_INVALID = 0x80000000, // remove invalid triangles
+ KCLMD_M_DROP = KCLMD_DROP_AUTO
+ | KCLMD_DROP_UNUSED
+ | KCLMD_DROP_FIXED
+ | KCLMD_DROP_INVALID,
+
+ KCLMD_RM_FACEDOWN = 1ull<<32, // remove face down drivable triangles
+ KCLMD_RM_FACEUP = 1ull<<33, // remove face up walls
+ KCLMD_M_RM = KCLMD_RM_FACEDOWN
+ | KCLMD_RM_FACEUP,
+
+ KCLMD_CONV_FACEUP = 1ull<<34, // convert face up walls to road
+ KCLMD_WEAK_WALLS = 1ull<<35, // OR 0x8000 to KCL flags of walls
+ KCLMD_NEW = 1ull<<36, // create a new KCL file even if nothing changed
+ KCLMD_SORT = 1ull<<37, // sort triangles
+ KCLMD_M_PATCH = KCLMD_M_DROP
+ | KCLMD_M_RM
+ | KCLMD_CONV_FACEUP
+ | KCLMD_WEAK_WALLS
+ | KCLMD_NEW
+ | KCLMD_SORT,
+
+ //--- tiny modes
+
+ KCLMD_S_TINY = 40,
+ KCLMD_TINY_0 = 0ull << KCLMD_S_TINY, // TINY levels
+ KCLMD_TINY_1 = 1ull << KCLMD_S_TINY,
+ KCLMD_TINY_2 = 2ull << KCLMD_S_TINY,
+ KCLMD_TINY_3 = 3ull << KCLMD_S_TINY,
+ KCLMD_TINY_4 = 4ull << KCLMD_S_TINY,
+ KCLMD_TINY_5 = 5ull << KCLMD_S_TINY,
+ KCLMD_TINY_6 = 6ull << KCLMD_S_TINY,
+ KCLMD_TINY_7 = 7ull << KCLMD_S_TINY,
+ KCLMD_M_TINY = KCLMD_TINY_7,
+
+
+ //--- hidden options
+
+ KCLMD_LOG = 1ull<<43, // enable kcl trace log to stdout
+ KCLMD_SILENT = 1ull<<44, // suppress kcl messages
+ KCLMD_POSLEN = 1ull<<45, // force length>=0 in CalcPointsTriData()
+ KCLMD_INPLACE = 1ull<<46, // force inplace patching
+ KCLMD_M_HIDDEN = KCLMD_LOG
+ | KCLMD_SILENT
+ | KCLMD_POSLEN
+ | KCLMD_INPLACE,
+
+ KCLMD_F_SCRIPT = 1ull<<50, // execute script first
+ KCLMD_F_HIDE = 1ull<<51, // help flag to hide modes in PrintKclMode()
+
+
+ //--- test mode
+
+ KCLMD_TEST = 1ull<<60, // reserved for testing
+
+
+ //--- summaries
+
+ KCLMD_M_DEFAULT = KCLMD_MTL // default settings
+ | KCLMD_DROP_AUTO,
+
+ KCLMD_M_FIX_ALL = KCLMD_M_DROP // general kcl fix mode
+ | KCLMD_M_RM
+ | KCLMD_NEW,
+
+ KCLMD_M_ALL = KCLMD_M_GENERAL // all relevant bits
+ | KCLMD_M_PATCH
+ | KCLMD_M_HIDDEN
+ | KCLMD_ADD_ROAD
+ | KCLMD_F_SCRIPT
+ | KCLMD_M_TINY
+ | KCLMD_TEST,
+
+ KCLMD_M_PRINT = KCLMD_M_ALL // all relevant bits for obj output
+ % ~KCLMD_ADD_ROAD
+ & ~KCLMD_IN_SWAP
+ & ~KCLMD_AUTO
+ & ~KCLMD_M_HEX
+ & ~KCLMD_M_HIDDEN,
+
+} kcl_mode_t;
+
+//-----------------------------------------------------------------------------
+
+extern int enable_kcl_drop_auto;
+extern kcl_mode_t KCL_MODE;
+
+void SetKclMode ( kcl_mode_t new_mode );
+int ScanOptKcl ( ccp arg );
+uint PrintKclMode( char *buf, uint bufsize, kcl_mode_t mode );
+ccp GetKclMode();
+void SetupKCL();
+
+extern Color_t user_color[N_KCL_USER_FLAGS];
+extern uint n_user_color;
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// kcl_t ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_t]]
+
+#define KCL_MAX_STAT_DEPTH 32
+#define KCL_MAX_TRIANGLES 0xffff
+#define KCL_MAX_PT_PER_TRI 50
+
+typedef struct kcl_t
+{
+ //--- base info
+
+ ccp fname; // alloced filename of loaded file
+ FileAttrib_t fatt; // file attribute
+ file_format_t fform; // FF_KCL | FF_KCL_TXT
+ file_format_t fform_outfile; // planned output format
+ int revision; // tool revision
+ char signature_info[9]; // info text of signature, found in vertex #0
+ float signature; // >0.0: signature number, found in vertex #0
+
+ //--- base settings
+
+ bool silent_octree; // true: create octree without comments
+ // always init with false
+ bool fast; // true: don't find duplicates
+ // init by 'KCL_MODE & KCLMD_FAST'
+ uint min_cube_size; // minimum cube size
+ // init by 'KCL_MIN_SIZE'
+ uint max_cube_size; // maximum cube size
+ // init by 'KCL_MAX_SIZE'
+ uint cube_blow; // blow up the cube to find tirangles
+ // init by 'KCL_BLOW'
+ uint max_cube_triangles; // maximum triangles per cube
+ // init by 'KCL_MAX_TRI'
+ uint max_octree_depth; // maximum octree depth
+ // init by 'KCL_MAX_DEPTH'
+
+ //--- file header data
+
+ double3 min_octree; // minimum coordinate values
+ u32 mask[3]; // masks for spatial index
+ u32 coord_rshift; // right shift for all coord
+ u32 y_lshift; // left shift for y values
+ u32 z_lshift; // left shift for z values
+ float unknown_0x10; // unknown header value
+ float unknown_0x38; // unknown header value
+
+ //--- triangle data
+
+ List_t tridata; // triangle data base
+ bool norm_valid; // true: all normal data is valid
+ bool used_valid; // true: used markers are valid
+ bool no_limit; // true: no triangle limit
+ bool limit_warning; // true: limit warning is already printed
+ double3 tri_minval; // minimum allowed triangle value,
+ // initialized with -1e9
+ double3 tri_maxval; // maximum allowed triangle value,
+ // initialized with +1e9
+ uint tri_inv_count; // number of invalid triangles
+ // all invalid are also fixed
+ // but not counted as 'tri_fix_count'
+ uint tri_fix_count; // number of fixed triangles
+ // this excludes 'tri_inv_count'
+
+ //--- octree data
+
+ u8 *octree; // NULL or pointer to octree
+ uint octree_size; // size of 'octree'
+ bool octree_valid; // octree & header data are valid
+ bool octree_alloced; // true: FREE(octree)
+ bool recreate_octree; // true: recreate octree before storing
+
+
+ //--- statistics about triangle points
+
+ double3 min; // min coord of all triangle points
+ double3 mean; // mean coord of all triangle points
+ double3 max; // max coord of all triangle points
+ double tmin_dist; // minimum triangle point distance
+ double tmax_dist; // maximum triangle point distance
+ bool min_max_valid; // true: all 4 vars of this part are valid
+
+ //--- raw data, created by CreateRawKCL()
+
+ u8 * raw_data; // NULL or data
+ uint raw_data_size; // size of 'raw_data'
+ bool raw_data_alloced; // true: FREE(raw_data)
+ bool model_modified; // the model was modified
+ // raw data is invalid
+
+ //--- flag database
+
+ ccp flag_fname; // path of flag file, alloced
+ bool flag_db_loaded; // true: flag db is loaded
+ bool accept_hex4; // true: accept '_FFFF'
+ bool accept_hex23; // true: accept '_TT_VVV'
+ FormatField_t flag_name; // list with names
+ FormatField_t flag_pattern; // list with patterns
+ FormatField_t flag_missing; // list with unresolved group names
+
+
+ //--- script flags
+
+ bool script_tri_removed; // true: triangle removed
+ bool script_tri_added; // true: triangle added
+ bool script_pt_modified; // true: points modified
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ /////////////// Statistics ==> LAST KCL DATA! ///////////////
+ ///////////////////////////////////////////////////////////////////////////
+
+ //--- statistics: base
+
+ bool stat_valid; // IMPORTANT: First statsitics data!
+ // true: all statistics are valid
+
+ //--- base statistics
+
+ uint mask_bits[3]; // number of 0 bits in mask
+ uint bcube_bits[3]; // number of base cube relevant bits
+ uint hash_bits; // number of bits in hash value
+ uint n_bcubes[3]; // number of base cubes per axis
+ uint total_bcubes; // total number of base cubes
+ uint bcube_width; // edge length of base cubes
+ double3 max_octree; // maximum coordinate values
+
+
+ //--- statistics: octree
+
+ u32 min_o_offset; // first cube node
+ u32 max_o_offset; // end of last cube node
+ u32 min_l_offset; // min found list offset
+ u32 max_l_offset; // max found list offset
+ uint n_cube_nodes; // number of octree cube nodes
+ // (each with 8 links)
+ uint total_cubes; // total number of cubes
+ uint n_trilist; // number of tri-list links
+
+
+ //--- statistics: octree lists
+
+ u8 *o_depth; // octree depth, N=n_octree
+ u16 *o_count; // octree ref counts, N=n_octree
+ u16 *l_count; // trilist ref counts, N=n_trilist
+
+ uint n_0_list; // num of triangle lists
+ uint n_0_link; // num of triangle links
+ uint n_tri_list; // num of triangle lists
+ uint n_tri_link; // num of triangle links
+ uint max_tri_len; // max triangles in a list
+ uint min_depth; // min octree depth with triangles
+ uint max_depth; // max octree depth
+ uint max_depth_tri_len[KCL_MAX_STAT_DEPTH];
+ // max triangles in a list,
+ // depth dependent
+ float ave_depth; // average depth
+ uint sum_tri_len; // sum of all list length's
+
+
+ //--- statistics: usage
+
+ uint n_invalid_tri_ref; // num of invalid tri references
+ uint n_tri_used; // num of used triangles
+
+} kcl_t;
+
+//-----------------------------------------------------------------------------
+
+extern kcl_t * kcl_ref; // NULL or reference KCL for calculations
+extern kcl_t * kcl_ref_prio; // NULL or prioreference KCL for calculations
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// KCL interface ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+const VarMap_t * SetupVarsKCL();
+
+void SetupReferenceKCL
+(
+ VarMap_t *vm // not NULL: define KCL variables here
+);
+
+void InitializeKCL ( kcl_t * kcl );
+void ResetKCL ( kcl_t * kcl );
+void ClearKCL ( kcl_t * kcl, bool init_kcl );
+void CopyKCL ( kcl_t * kcl, bool init_kcl, const kcl_t * src );
+
+void LoadParametersKCL
+(
+ ccp log_prefix // not NULL:
+ // print log message with prefix
+);
+
+bool TransformKCL ( kcl_t * kcl );
+enumError CreateOctreeKCL ( kcl_t * kcl );
+
+void ResetStatisticsKCL ( kcl_t * kcl );
+void CalcStatisticsKCL ( kcl_t * kcl );
+void CalcMinMaxKCL ( kcl_t * kcl );
+uint CalcBlowSizeKCL ( kcl_t * kcl );
+bool DropSortTriangles ( kcl_t * kcl );
+
+bool DropSortHelper
+(
+ kcl_t *kcl, // valid KCL
+ uint drop_mask, // not 0: drop triangles with set bits
+ bool sort // true: sort triangles
+);
+
+bool KCL_ACTION_LOG ( const char * format, ... )
+ __attribute__ ((__format__(__printf__,1,2)));
+
+///////////////////////////////////////////////////////////////////////////////
+
+uint CheckMetricsTriData
+(
+ // check length and minimal height of triangles
+
+ kcl_tridata_t *td, // valid pointer to first record
+ uint n, // number of records to process
+ kcl_t *kcl // not NULL: store statistics
+);
+
+//-----------------------------------------------------------------------------
+
+uint CalcPointsTriData
+(
+ // calculate 'pt' using 'length' & 'normal'
+ // returns the number of fixes
+
+ kcl_tridata_t *td, // valid pointer to first record
+ uint n, // number of records to process
+ kcl_t *kcl, // not NULL: store statistics
+ bool use_minmax // true & 'kcl': use 'tri_minval' and 'tri_maxval'
+);
+
+//-----------------------------------------------------------------------------
+
+void CalcNormalsTriData
+(
+ // calculate 'length' & 'normal' using 'pt'
+ // the calculation is only done, if 'TD_INVALID_NORM'
+
+ kcl_t *kcl, // valid KCL
+ kcl_tridata_t *td, // valid pointer to first record
+ uint n // number of records to process
+);
+
+//-----------------------------------------------------------------------------
+
+void CalcNormalsKCL
+(
+ // calculate 'length' & 'normal' using 'pt'
+ // the calculation is only done, if '!kcl->norm_valid'
+
+ kcl_t *kcl, // valid KCL
+ bool force // true: ignore 'kcl->norm_valid'
+);
+
+//-----------------------------------------------------------------------------
+
+void RoundNormalsKCL
+(
+ // round the normal values
+
+ kcl_t *kcl, // valid KCL
+ int round_pow2 // round to '1/(2^round_pow2)'
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *GetTridataKCL
+(
+ kcl_t *kcl, // valid KCL
+ uint tri_index // triangle index
+);
+
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_tri_param_t]]
+
+typedef struct kcl_tri_param_t
+{
+ kcl_t *kcl; // valid KCL data structure
+ u32 kcl_flag; // value of kcl flag
+ bool is_orig; // true: is original data
+
+ const double3 *norm; // NULL or pointer to normal
+ // => auto detection to swap pt2,pt3
+ uint swap_count; // not NULL: increment on swap
+}
+kcl_tri_param_t;
+
+//-----------------------------------------------------------------------------
+
+static inline void InitializeTriParam
+ ( kcl_tri_param_t *tp, kcl_t *kcl, u32 kcl_flag )
+{
+ DASSERT(tp);
+ DASSERT(kcl);
+ memset(tp,0,sizeof(*tp));
+ tp->kcl = kcl;
+ tp->kcl_flag = kcl_flag;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+kcl_tridata_t * PrepareAppendTrianglesKCL
+(
+ // Grows the triangle field and the 'used' count.
+ // Returns a pointer to the first triangle.
+ // If to many triangles:
+ // => a warning is printed, but only once for a kcl. NULL is returned
+
+ kcl_t *kcl, // valid KCL data structure
+ uint n_append // number of triangles to append
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t * AppendTriangleKCL
+(
+ // returns the new triangle, or NULL if failed (to many triangles)
+
+ kcl_tri_param_t *par, // valid data structure
+ const double3 *pt1, // pointer to point #1
+ const double3 *pt2, // pointer to point #2
+ const double3 *pt3 // pointer to point #3
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t * AppendTriangleKCLp
+(
+ // returns the new triangle, or NULL if failed (to many triangles)
+
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ const double3 *pt1, // pointer to point #1
+ const double3 *pt2, // pointer to point #2
+ const double3 *pt3 // pointer to point #3
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *AppendQuadrilateralKCL
+(
+ // returns the new triangle, or NULL if failed (to many triangles)
+
+ kcl_tri_param_t *par, // valid data structure
+ const double3 *pt1, // pointer to point #1
+ const double3 *pt2, // pointer to point #2
+ const double3 *pt3, // pointer to point #3
+ const double3 *pt4 // pointer to point #4
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *AppendQuadrilateralKCLp
+(
+ // returns the new triangle, or NULL if failed (to many triangles)
+
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ const double3 *pt1, // pointer to point #1
+ const double3 *pt2, // pointer to point #2
+ const double3 *pt3, // pointer to point #3
+ const double3 *pt4 // pointer to point #4
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t * AppendTrianglesKCL
+(
+ // returns the new triangle, or NULL if failed (to many triangles)
+
+ kcl_tri_param_t *par, // valid data structure
+ const double3 *pt1, // pointer to first point
+ int pt_delta, // delta in bytes to next point, <0 possible
+ uint n_pt // number of points
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t * AppendTrianglesKCLp
+(
+ // returns the new triangle, or NULL if failed (to many triangles)
+
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ const double3 *pt1, // pointer to first point
+ int pt_delta, // delta in bytes to next point, <0 possible
+ uint n_pt // number of points
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *AppendOctahedronKCL
+(
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ octahedron_t *oct // valid octahedron data
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *AppendCuboidKCL
+(
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ cuboid_t *c // valid cuboid data
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *AppendPyramidKCL
+(
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ const double3 *apex, // the apex of the pyramid
+ const double3 *pt1, // pointer to first point
+ uint pt_delta, // delta in bytes to next point
+ uint n_pt, // number of points
+ bool reverse // true: reverse face orientation
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t *AppendPrismKCL
+(
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ const double3 *axis1, // first axis point
+ const double3 *axis2, // second axis point
+ const double3 *dir, // NULL or direction of first edge
+ double r, // radius
+ uint n_side, // number of sides, max=100
+ uint mode, // bitfield: 0=prism, 1=antiprism
+ u32 base_flag, // color of base, -1:no base
+ double base_height, // height of base, truncated to 40% of length
+ // if 0.0: use a plane, otherwise a pyramid
+ u32 arrow_flag, // color of arror peak at axis2, -1:no arrow
+ double arrow_size, // relative size of arrow (multiplied by *r),
+ // truncated to length. no arrow if <=0.0
+ bool arrow_flip // true: flip direction of arrow
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t * AppendCylinderKCL
+(
+ kcl_t *kcl, // valid KCL data structure
+ u32 kcl_flag, // value of kcl flag
+ const double3 *pos, // base point of cylinder
+ const double3 *p_scale, // scale. If NULL: assume v(1,1,1)
+ double scale_factor, // Scale is multiplied by this factor
+ const double3 *rotate, // NULL or rotation vector
+ uint n_side, // number of sides, max=100
+ u32 base_flag // color of bases, -1:no base
+);
+
+//-----------------------------------------------------------------------------
+
+kcl_tridata_t * AppendJoistKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ u32 kcl_flag, // parameter for AppendTrianglesKCLp()
+ double length, // length of corpus
+ const double3 *p1, // first point
+ const double3 *p2, // second point
+ const double3 *p3, // helper point to find direction
+ int n_mark, // >0: add marker representing the number (modulo)
+ u32 mark5_flag // >0: replace 5 marker by one of this color
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+enumError ScanRawKCL
+(
+ kcl_t * kcl, // KCL data structure
+ bool init_kcl, // true: initialize 'kcl' first
+ const void * data, // data to scan
+ uint data_size, // size of 'data'
+ bool use_data // true: data is valid on 'kcl' live time
+);
+
+//-----------------------------------------------------------------------------
+
+enumError ScanTextKCL
+(
+ kcl_t * kcl, // KCL data structure
+ bool init_kcl, // true: initialize 'kcl' first
+ const void * data, // data to scan
+ uint data_size, // size of 'data'
+ file_format_t fform // FF_UNNOWN or file format
+);
+
+//-----------------------------------------------------------------------------
+
+enumError ScanKCL
+(
+ kcl_t * kcl, // KCL data structure
+ bool init_kcl, // true: initialize 'kcl' first
+ const void * data, // data to scan
+ uint data_size, // size of 'data'
+ bool use_data, // true: data is valid on 'kcl' live time
+ CheckMode_t mode // not NULL: call CheckKCL(mode)
+);
+
+//-----------------------------------------------------------------------------
+
+struct raw_data_t;
+
+enumError ScanRawDataKCL
+(
+ kcl_t * kcl, // KCL data structure
+ bool init_kcl, // true: initialize 'kcl' first
+ struct raw_data_t * raw, // valid raw data
+ bool move_data, // true: move 'raw.data' to 'kcl'
+ CheckMode_t mode // not NULL: call CheckKCL(mode)
+);
+
+//-----------------------------------------------------------------------------
+
+enumError LoadKCL
+(
+ kcl_t * kcl, // KCL data structure
+ bool init_kcl, // true: initialize 'kcl' first
+ ccp fname, // valid pointer to filenname
+ bool ignore_no_file, // ignore if file does not exists
+ // and return warning ERR_NOT_EXISTS
+ CheckMode_t mode // not NULL: call CheckKCL(mode)
+);
+
+//-----------------------------------------------------------------------------
+
+int ScanOptLoadKcl ( ccp arg );
+kcl_t * LoadReferenceKCL();
+kcl_t * CreateReferenceKCL();
+void UnloadAutoReferenceKCL();
+void DefineAutoLoadReferenceKCL ( ccp fname, ccp ext );
+
+static inline kcl_t * GetReferenceKCL()
+ { return kcl_ref_prio ? kcl_ref_prio : LoadReferenceKCL(); }
+
+///////////////////////////////////////////////////////////////////////////////
+
+enumError CreateRawKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ bool add_sig // true: add signature
+);
+
+//-----------------------------------------------------------------------------
+
+enumError SaveRawKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ ccp fname, // filename of destination
+ bool set_time // true: set time stamps
+);
+
+//-----------------------------------------------------------------------------
+
+enumError SaveTextKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ ccp fname, // filename of destination
+ bool set_time // true: set time stamps
+);
+
+//-----------------------------------------------------------------------------
+
+enumError DumpKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ ccp fname, // filename of destination
+ bool print_tridata, // true: triangle list
+ uint print_octree // octree print level (0..2)
+);
+
+//-----------------------------------------------------------------------------
+
+enumError DumpTrianglesKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ ccp fname // filename of destination
+);
+
+//-----------------------------------------------------------------------------
+
+enumError ListTrianglesKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ ccp fname, // filename of destination
+ bool print_normals, // true: print large tables
+ uint precision // floating point pre: 0=+0, .. 3=+6
+);
+
+//-----------------------------------------------------------------------------
+
+enumError TraverseOctreeKCL
+(
+ kcl_t *kcl, // pointer to valid KCL
+ FILE *f, // output file, if NULL set verbosity:=0
+ double3 pt, // point to analyze
+ bool print_tri_val, // true: print tri values instead of index
+ uint verbosity // verbose level
+ // >=1: print base calculations
+ // >=2: print step calculations
+);
+
+//-----------------------------------------------------------------------------
+
+double FallKCL
+(
+ // returns the height or -1.0 on fail
+
+ kcl_t *kcl, // pointer to valid KCL
+ FILE *f, // output file, if NULL: verbose:=0
+ double3 pt, // mid point of cube to analyze
+ uint width, // width of cube
+ int verbosity, // verbose level
+ // <=0: silent
+ // >=1: log triangle search
+ // >=2: print base calculations
+ // >=3: print step calculations
+ u32 type_mask, // kcl type selector (bit field)
+ int *res_kcl_flag // not NULL: store KCL flag here
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+int CheckKCL
+(
+ // returns number of errors
+
+ kcl_t * kcl, // pointer to valid KCL
+ CheckMode_t mode // print mode
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// KCL flags ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void LoadFlagFileKCL
+(
+ kcl_t * kcl // pointer to valid KCL
+);
+
+//-----------------------------------------------------------------------------
+
+int GetFlagByNameKCL
+(
+ kcl_t * kcl, // pointer to valid KCL
+ ccp name, // upper case name to search
+ int new_value // return value if not found
+ // >0: used as new value
+
+ // The name is searched in 4 steps:
+ // 1. Search literal in 'flag_name' (ignore case)
+ // 2. Search pattern in 'flag_pattern' (ignore case)
+ // 3. Search pattern in 'flag_missing' (ignore case)
+ // 4. Analyze the last 5 characters for '_ffff'
+ // 5. Analyze the last 7 characters for '_tt_vvv'
+ // 6. Use 'new_value'
+);
+
+//-----------------------------------------------------------------------------
+
+uint * AllocFlagCount();
+
+uint CountFlagsKCL
+(
+ // returns the total number of flag groups
+
+ const kcl_t * kcl, // pointer to valid KCL
+ uint * count // pointer to field with NNN_KCL_FLAG elements
+);
+
+ccp GetGroupNameKCL ( uint kcl_flag, bool add_info );
+uint GetExportFlagKCL ( uint kcl_flag );
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// KCL Type transformations ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+extern int have_kcl_patch_count;
+extern StringField_t kcl_script_list;
+extern u16 *patch_kcl_flag; // NULL or 'N_KCL_FLAG' elements
+
+//-----------------------------------------------------------------------------
+
+int ScanOptKclScript ( ccp arg );
+
+void SetupPatchKclFlag();
+void ResetPatchKclFlag();
+void PurgePatchKclFlag();
+void RemovePatchKclFlag();
+int ScanOptKclFlag ( ccp arg );
+int ScanOptTriArea ( ccp arg );
+int ScanOptTriHeight ( ccp arg );
+
+//-----------------------------------------------------------------------------
+
+bool PatchRawDataKCL
+(
+ void * data, // data to scan
+ uint data_size, // size of 'data'
+ ccp fname // file name for error messages
+);
+
+//-----------------------------------------------------------------------------
+
+bool PatchKCL
+(
+ kcl_t * kcl // pointer to valid KCL
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// octree iterator ///////////////
+///////////////////////////////////////////////////////////////////////////////
+// [[kcl_cube_t]]
+
+typedef struct kcl_cube_t
+{
+ s32 min[3]; // minimum cube coordinates
+ s32 max[3]; // maximum cube coordinates
+
+} kcl_cube_t;
+
+//-----------------------------------------------------------------------------
+// [[kcl_cube_list_t]]
+
+#if SUPPORT_KCL_CUBE
+#define MAX_CUBE_TRI 10
+
+typedef struct kcl_cube_list_t
+{
+ uint n; // number of used cubes
+ kcl_cube_t cube[MAX_CUBE_TRI]; // list of cubes
+
+} kcl_cube_list_t;
+
+#endif
+//-----------------------------------------------------------------------------
+// [[kcl_tri_t]]
+
+typedef struct kcl_tri_t
+{
+ s32 pt[3][3]; // normalized positions of 3 points
+ kcl_cube_t cube; // min and max coordinates
+ u32 select; // select level
+
+} kcl_tri_t;
+
+///////////////////////////////////////////////////////////////////////////////
+
+typedef int (*oct_func)
+(
+ kcl_t *kcl, // pointer to valid KCL
+ void *param, // user parameter
+ const kcl_cube_t *cube, // pointer to current cube geometry
+ // relative to kcl->min_octree;
+ const u16 *tri_list, // NULL or pointer to triangle index list
+ uint n_list // number of elements in 'tri_list'
+);
+
+///////////////////////////////////////////////////////////////////////////////
+
+int OctreeIteratorKCL
+(
+ kcl_t *kcl, // pointer to valid KCL
+ oct_func func, // call back function
+ void *param // user parameter
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// draw png ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+extern bool opt_png; // if true: PNG drawing is enabled
+extern uint opt_png_pix_size; // pixel size, =0: disabled
+extern uint opt_png_aalise; // a factor for antialising
+extern int opt_png_x1; // x1<x2: left border
+extern int opt_png_x2; // x1<x2: right border
+extern int opt_png_y1; // y1<y2: bop forder
+extern int opt_png_y2; // y1<y2: bottom border
+extern u32 opt_png_type_mask; // typemask for KCL selection.
+extern bool opt_png_rm; // true: remove unused triangles
+
+//-----------------------------------------------------------------------------
+
+extern int ScanOptPng ( ccp arg );
+
+struct kmp_t;
+enumError SaveImageKCL
+(
+ struct kmp_t * kmp, // pointer to valid KMP
+ kcl_t * kcl, // pointer to valid KCL
+ ccp fname, // filename of destination
+ bool set_time // true: set time stamps
+);
+
+//
+///////////////////////////////////////////////////////////////////////////////
+/////////////// END ///////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#endif // SZS_LIB_KCL_H