Posted to tcl by hypnotoad at Tue Oct 09 23:50:43 GMT 2018view raw
- /*
- ** This file is generated by the /Users/seandeelywoods/build/odie/odielib/make.tcl script
- ** any changes will be overwritten the next time it is run
- */
- /* This file was generated by practcl */
- #include <tcl.h>
- #include <tclOO.h>
- #include "odielibc.h"
- #include <assert.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include "inline_list.h"
- #include <limits.h>
- #include <float.h>
- #include <strings.h>
- /* BEGIN generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/hash/hash.tcl generate-cfile-header */
- /****** This file is copied from SQLite and modified *******
- **
- ** 2001 September 22
- **
- ** The author disclaims copyright to this source code. In place of
- ** a legal notice, here is a blessing:
- **
- ** May you do good and not evil.
- ** May you find forgiveness for yourself and forgive others.
- ** May you share freely, never taking more than you give.
- **
- *************************************************************************
- ** This is the implementation of generic hash-tables
- ** used in SQLite.
- **
- */
- #define uptr unsigned int
- #define Addr(X) ((uptr)X)
- #define readiMalloc malloc
- #define readiFree free
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/hash/hash.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/btree/btree.tcl generate-cfile-header */
- static void TreeClearNode(TreeElem *p, void (*xFree)(void*));
- static TreeElem *TreeFindNthElem(Tree *tree, int n);
- static void TreeBalance(TreeElem **ppElem);
- static void *TreeInsertElement(Tree *pTree, void *key, void *data);
- static TreeElem *TreeDeleteNthElem(TreeElem **ppTop, int N);
- static TreeElem *TreeDeleteElem(Tree *tree, const void *key);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/btree/btree.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/odiemath/odiemath.tcl generate-cfile-header */
- double OdieGrain=2.5;
- double OdieTolerance=0.001;
- static inline int Odie_GetMatrixElementFromObj(Tcl_Interp *interp,Tcl_Obj *objPtr,double *R,int idx);
- static inline unsigned int hashInt(int x);
- static inline long intCoord(double x);
- static inline unsigned int hashPoint(VECTORXY p);
- static inline unsigned int hashVectorXY(VECTORXY p);
- static inline unsigned int hashVectorXYZ(VECTORXYZ p);
- static inline double roundCoord(double x);
- static inline int hashCoord(double x, double y);
- static inline int hashCoord3d(double x, double y,double z);
- static inline int floatCompare(double x0, double x1);
- static inline void GridCoord(double *x, double *y);
- static int TclCmd_odiemath_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_dist3d(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_grid_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_grid_round(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_grid_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_list_round(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_list_to_int(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_matrix_rotate_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_matrix_rotate_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_perpendicular(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_normal_2d(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_parallel_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_vector_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_vector_rotate_and_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_vector_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_vector_translate_and_zoom(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_grid(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odiemath_tolerance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/odiemath/odiemath.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/module.ini generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/aabb.tcl generate-cfile-header */
- static inline void VectorXYZ_AABB_Normalize(AABBXYZ R);
- static void VectorXYZ_AABB_Copy(AABBXYZ dest,AABBXYZ src);
- static inline int VectorXYZ_AABB_Within(VectorXYZ POINT,AABBXYZ R);
- static inline int VectorXYZ_BBOX_Overlap_TwoVectors(VectorXYZ A1,VectorXYZ A2,VectorXYZ B1,VectorXYZ B2);
- static inline int AABB_AABB_Intersect(AABBXYZ A,AABBXYZ B);
- static inline void VectorXYZ_AABB_Measure(VectorXYZ POINT,AABBXYZ R);
- static inline void AABB_AABB_Combine(AABBXYZ B,AABBXYZ A);
- static inline void VectorXYZ_AABB_Reset(AABBXYZ R);
- static int TclCmd_odie_aabb_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_overlap_two_vectors(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_measure(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_faces(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_from_vectorxyz(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_from_line(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_from_center_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_aabb_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/aabb.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine2d.tcl generate-cfile-header */
- static int TclCmd_affine2d_apply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine2d_combine(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine2d_rotation_from_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine2d_rotation_from_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine2d.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine3d.tcl generate-cfile-header */
- static inline int affine_Compare(AFFINE A,AFFINE B);
- static inline void affine_rotate_spin(AFFINE RESULT,SCALER psi);
- static void Odie_Affine_From_Normal(AFFINE RESULT,VectorXYZ NORMAL);
- static int TclCmd_affine4x4_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_identity(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_translation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_rotate_nutation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_rotate_precession(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_rotate_spin(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_from_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_multiply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_multiply_inplace(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_inverse(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_affine4x4_from_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine3d.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/bbox.tcl generate-cfile-header */
- static inline void VectorXY_BBOX_Copy(BBOXXY dest,BBOXXY src);
- static inline void VectorXY_BBOX_Reset(BBOXXY R);
- static inline int VectorXY_IsBetween_BBOX(VectorXY POINT,VectorXY A,VectorXY B);
- static inline int VectorXY_Within_BBOX(VectorXY POINT,BBOXXY bbox);
- static inline int XY_Within_BBOX(double x, double y,BBOXXY bbox);
- static inline void VectorXY_BBOX_Measure(VectorXY POINT,BBOXXY bbox);
- static inline int BBOX_BBOX_Intersect(BBOXXY A,BBOXXY B);
- static int TclCmd_odie_bbox_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_bbox_measure(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_bbox_elements(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_bbox_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_bbox_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/bbox.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/quaternion.tcl generate-cfile-header */
- static inline void Quaternion_From_Normal(QUATERNION RESULT,VectorXYZ from,VectorXYZ to);
- static int TclCmd_quaternion_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_multiply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_divide(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_square_root(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_from_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_rotate_by_quaternion(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_to_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_quaternion_from_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/quaternion.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector.tcl generate-cfile-header */
- static double Vector_Tolerance=0.01;
- static double Vector_Tolerance_Sq=0.0001;
- static Odie_MatrixObj *Odie_Matrix_To_Fit(Odie_MatrixObj *A,Odie_MatrixObj *B);
- static inline double Vector_GridScaler(double x,double grid,double grain);
- static int TclCmd_odie_tolerance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_to_list(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_index(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_is_null(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_reciprocal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_dot_product(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_to_matrix(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_to_fuzzy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_vector_length_squared(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_grid(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_odie_gridvar(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector2d.tcl generate-cfile-header */
- /*
- ** Routines in this file are designed to work with double numbers
- ** directly. Useful for screen operations where X Y lists are used
- */
- static inline int Vector2d_PointIsOnSegment(double x,double y,double x1,double y1,double x2,double y2);
- static int TclCmd_vector2d_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_affine_apply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_dotproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_crossproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_rightof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_rotate_and_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_translate_and_zoom(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_point_on_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_line_circle_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_line_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_line_overlap(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector2d_colinear(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector2d.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector3d.tcl generate-cfile-header */
- static int TclCmd_vector3d_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector3d_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector3d_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector3d_orthagonal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector3d_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vector3d_distanceSq(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector3d.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorn.tcl generate-cfile-header */
- static int TclCmd_vectorN_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorN_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorN_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorN_scalevar(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorn.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxy.tcl generate-cfile-header */
- static inline void VectorXY_GridAlign(VECTORXYZ A,double grid);
- static inline void VectorXY_Midpoint(VECTORXY C,VECTORXY A,VECTORXY B);
- static int TclCmd_vectorxy_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_add_stream(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_toint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_crossproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_normalize(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_dotproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_rightof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_rotate_and_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_translate_and_zoom(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxy_flatten(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxy.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxyz.tcl generate-cfile-header */
- static inline void VectorXYZ_Scale(VECTOR A,SCALER S);
- static inline void VectorXYZ_Zero(VECTORXYZ A);
- static inline void VectorXYZ_GridAlign(VECTORXYZ A,double grid);
- static inline void VectorXYZ_Copy(VECTORXYZ B,VECTORXYZ A);
- static inline int VectorXYZ_SamePoint(VECTORXYZ A,VECTORXYZ B);
- static inline int VectorXYZ_IsZero(VECTORXYZ A);
- static inline void VectorXYZ_Cross_Product(VectorXYZ C,VectorXYZ A,VectorXYZ B);
- static inline void VectorXYZ_Add(VECTORXYZ C,VECTORXYZ A,VECTORXYZ B);
- static inline void VectorXYZ_Subtract(VECTORXYZ C,VECTORXYZ A,VECTORXYZ B);
- static inline int VectorXYZ_IsOrthagonal(VECTORXYZ A,VECTORXYZ B);
- static inline void VectorXYZ_Midpoint(VECTORXYZ C,VECTORXYZ A,VECTORXYZ B);
- static inline double VectorXYZ_Distance(VECTORXYZ A,VECTORXYZ B);
- static inline double VectorXYZ_DistanceSq(VECTORXYZ A,VECTORXYZ B);
- static inline double VectorXYZ_Dot_Product(VectorXYZ A,VectorXYZ B);
- static inline void VectorXYZ_MatrixMultiply(VECTORXYZ R,VECTORXYZ A,AFFINE M);
- static inline double VectorXYZ_MagnitudeSq(VECTOR A);
- static inline double VectorXYZ_Magnitude(VECTOR A);
- static inline double VectorXYZ_MagnitudeInvSqr(VECTOR A);
- static inline int VectorXYZ_Normalize(VectorXYZ A);
- static inline int VectorXYZ_PointIsOnSegment(VectorXYZ POINT,VectorXYZ A,VectorXYZ B);
- static inline int VectorXYZ_AxisOfNormal(VectorXYZ NORMAL);
- static inline int VectorXYZ_NormalStrictAxisAligned(VectorXYZ NORMAL);
- static inline int VectorXYZ_AxisAligned(VectorXYZ A,VectorXYZ B,VectorXYZ C);
- static inline int VectorXYZ_BendDirection(VectorXYZ A,VectorXYZ B,VectorXYZ C);
- static inline double VectorXYZ_Angle_Three_Point(VectorXYZ A,VectorXYZ B,VectorXYZ C,VectorXYZ normal);
- static inline int VectorXYZ_IsColinear(VectorXYZ A,VectorXYZ B,VectorXYZ C);
- static inline int VectorXYZ_IsCoplaner(VectorXYZ x1,VectorXYZ x2,VectorXYZ x3,VectorXYZ x4);
- static inline int VectorXYZ_LineLineCoincident(
- VectorXYZ A1, VectorXYZ A2, VectorXYZ B1, VectorXYZ B2,
- VectorXYZ ICEPT1, VectorXYZ ICEPT2
- );
- static inline int VectorXYZ_LineLineIntersect(
- VectorXYZ p1, VectorXYZ p2, VectorXYZ p3, VectorXYZ p4,
- VectorXYZ pA, VectorXYZ pB, double *mua, double *mub
- );
- static double VectorXYZ_ClosestPointOnSegment (
- VectorXYZ A, VectorXYZ B, /* End points of the line segment */
- VectorXYZ X, /* The point outside the line */
- VectorXYZ R /* Write closest point on line segment here */
- );
- static int VectorXYX_solve3by3(double *m);
- static double VectorXYZ_TriangleLineIntersect(
- VectorXYZ A, VectorXYZ B, VectorXYZ C, /* The triangle we are trying to intersect */
- VectorXYZ pStart, /* Start of the line segment */
- VectorXYZ pEnd, /* End of the line segment */
- VectorXYZ pIntersect /* Point of intersection written here if not NULL */
- );
- static inline void VectorXYZ_Normal_of_Three_Points(VectorXYZ normal,VectorXYZ A,VectorXYZ B,VectorXYZ C);
- static int TclCmd_vectorxyz_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_zero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_polygon_normal_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_toint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_add_inplace(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_orthagonal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_cross_product(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_dot_product(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_transform(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_distanceSq(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_length_inv_sqr(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_normalize(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_point_on_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_point_on_segment_x(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_axis_of_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_bend_direction(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_angle_three_points(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_colinear(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_coplaner(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_linelinecoincident_int(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_linelinecoincident(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_linelineintersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_linelineintersect_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_sizeof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_closest_point_on_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_point_in_triangle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_triangle_line_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_line_sphere_intersect_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_line_sphere_intersect_area(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_line_sphere_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_polygon_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_polygon_center(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_vectorxyz_flatten(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxyz.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/cmatrixforms.tcl generate-cfile-header */
- const MatrixForm MatrixForms[] = {
- { MATFORM_null, "null", 0 , 0, "A matrix of arbitrary size", NULL },
- { MATFORM_aabb_xyz, "aabb_xyz", 6, 1, "An axis aligned bounding box in 3 dimensions", NULL },
- { MATFORM_affine, "affine", 4, 4, "A 4x4 affine matrix", Matrix_To_affine },
- { MATFORM_bbox_xy, "bbox_xy", 4, 1, "A 2 dimensional vector: X Y", Matrix_To_cartesian },
- { MATFORM_cylindrical, "cylindrical", 3, 1, "A 3 dimensional vector: RADIUS THETA Z", Matrix_To_cylindrical },
- { MATFORM_euler, "euler", 3, 1, "A 3 dimensional rotation: X Y Z", NULL },
- { MATFORM_heading, "heading", 3, 1, "A 3 dimensional rotation: yaw pitch roll", NULL },
- { MATFORM_mat2, "mat2", 2, 2, "A 2x2 matrix", NULL },
- { MATFORM_mat3, "mat3", 3, 3, "A 3x3 matrix", NULL },
- { MATFORM_mat4, "mat4", 4, 4, "A 4x4 matrix", NULL },
- { MATFORM_polar, "polar", 2, 1, "A 2 dimensional vector: RADIUS THETA", Matrix_To_cylindrical },
- { MATFORM_quaternion, "quaternion", 4, 1, "A quaternion: W X Y Z", Matrix_To_quaternion },
- { MATFORM_scaler, "scaler", 1, 1, "A scaler (1x1)", NULL },
- { MATFORM_spherical, "spherical", 3, 1, "A 3 dimensional vector: RADIUS THETA PHI", Matrix_To_spherical },
- { MATFORM_unknown, "unknown", 0 , 0, "A matrix of arbitrary size (but less than 4x4)", NULL },
- { MATFORM_vector_xy, "vector_xy", 2, 1, "A 2 dimensional vector: X Y", Matrix_To_cartesian },
- { MATFORM_vector_xyz, "vector_xyz", 3, 1, "A 3 dimensional vector: X Y Z", Matrix_To_cartesian },
- { MATFORM_vector_xyzw, "vector_xyzw", 4, 1, "A 4 dimensional vector: X Y Z W", Matrix_To_cartesian }
- };
- /* Module wide constants */
- const Tcl_ObjType *NumArrayType;
- const Tcl_ObjType *odieMatrixType;
- static int TclCmd_matrix_to_aabb_xyz(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_affine(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_bbox_xy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_cylindrical(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_heading(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_mat2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_mat3(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_mat4(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_null(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_polar(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_quaternion(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_scaler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_spherical(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_unknown(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_vector_xy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_vector_xyz(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_matrix_to_vector_xyzw(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/cmatrixforms.tcl generate-cfile-header */
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/module.ini generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/fuzzy/fuzzy.tcl generate-cfile-header */
- #ifdef _MSC_VER
- # define Odie_IsInfinite(d) (!(_finite((d))))
- # define Odie_IsNaN(d) (_isnan((d)))
- #else
- # define Odie_IsInfinite(d) ((d) > DBL_MAX || (d) < -DBL_MAX)
- # ifdef NO_ISNAN
- # define Odie_IsNaN(d) ((d) != (d))
- # else
- # define Odie_IsNaN(d) (isnan(d))
- # endif
- #endif
- static int TclCmd_tcl_mathfunc_to_fuzzy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_tcl_mathfunc_fuzzy_abs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_tcl_mathfunc_fuzzy_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_tcl_mathfunc_fuzzy_is_zero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_tcl_mathfunc_fuzzy_gt_zero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_tcl_mathfunc_fuzzy_epsilon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/fuzzy/fuzzy.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/module.ini generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/triangulate.tcl generate-cfile-header */
- #ifndef IRM_EPSILON
- #define IRM_EPSILON FLT_EPSILON
- #endif
- #ifndef M_PI
- # define M_PI 3.1415926535898
- #endif
- static int TclCmd_triag_test_rightof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_triag_test_dotprod(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_triag_test_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_triag_test_ideal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/triangulate.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygon.tcl generate-cfile-header */
- static inline int Odie_IsColinear(double x1,double y1,double x2,double y2,double x3,double y3);
- static inline double dist(double x0, double y0, double x1, double y1);
- static inline int withinPolygon(Odie_Polygon *p, double x, double y);
- static int TclCmd_polygon_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_simplify(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_area(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_bbox(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_info(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_center(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_canvascoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_coords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_xycoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_edges(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_bend(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_is_convex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_segments(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_rectangle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_vector_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_hexagon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_poly_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_drawobj_orientation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_corners(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_hexgrid_location(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_hexgrid_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygon_squaregrid_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygon.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygonxyz.tcl generate-cfile-header */
- static inline int Odie_FaceXYZ_Compare(Odie_FaceXYZ *A,Odie_FaceXYZ *B);
- static inline int Odie_FaceXYZ_Coplaner(Odie_FaceXYZ *A,Odie_FaceXYZ *B);
- static inline int PolygonUV_Within(Odie_FaceXYZ *p, double x, double y);
- static inline int Odie_FaceXYZ_Within(Odie_FaceXYZ *p, VectorXYZ POINT);
- static int Odie_FaceXYZ_IntersectTest(Odie_FaceXYZ *p1,Odie_FaceXYZ *p2);
- static double Odie_FaceXYZ_AreaOfIntersection(Odie_FaceXYZ *p1,Odie_FaceXYZ *p2,double *xin,double *yin);
- static int TclCmd_polygonxyz_info(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_createxy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_simplify(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_id(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_area(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_bbox(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_bend(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_center(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_is_2d(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_is_convex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_nVertex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_radius(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_rotation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_rotation_inv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_axis_of_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_canvascoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_coords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_intcoordsxy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_intcoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_edges(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_triangles(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_uvcoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_xycoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_coplaner(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_flipped(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_side(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_intersect_test(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_intersect_test_uv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_intersect_uv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_points_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_polygonxyz_within_set(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygonxyz.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/segset.tcl generate-cfile-header */
- static void SegmentSet_Delete(ClientData clientData);
- static int SegmentSet_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- );
- static int SegmentSet_Cleanup_Coincident(SegmentSet *pSet,Segment *pAB);
- static int Segment_OnList(Segment *pSeg, Link *pList);
- static Segment *SegmentSet_FindById(SegmentSet *p, int id);
- static void Segment_Imprint(Segment *pSrc,Segment *pDest);
- static void Segment_SetToFrom(SegmentSet *pSet, Segment *p, VECTORXYZ from, VECTORXYZ to);
- static inline Segment *Segment_Create(SegmentSet *pSet,int newid);
- static inline void SegmentSetRemove(SegmentSet *pSet, Segment *p);
- static inline void SegRelink(SegmentSet *pSet, Segment *p);
- static inline void SegmentSetClear(SegmentSet *pSet);
- static inline void SegmentSetStep(SegmentSet *pSet);
- static int SegmentSet_AddVertex(SegmentSet *pSet,VectorXYZ A);
- static int SegmentSet_Interference_Check(SegmentSet *pSet,VectorXYZ A,VectorXYZ B);
- static int SegmentSet_Edge_Connection(SegmentSet *pSet,VectorXYZ A,int comptid,VectorXYZ RESULT);
- static int SegmentSet_Convex_Connection(SegmentSet *pSet,Segment *pAB,int back,VectorXYZ RESULT);
- static int SegmentSetNextBend(
- SegmentSet *pSet,
- Segment *pAB,
- int backwards,
- Segment **ppSeg, /* OUT: First segment clockwise from xR,yR->xV,yV */
- int *pfBack, /* OUT: True if output segment goes backwards */
- int *pfBend, /* OUT: Bend direction */
- double *pfAngle
- );
- static int SegmentSet_SelfCheck(Tcl_Interp *interp, SegmentSet *p);
- static Link *SegmentSet_Segments_AtVertex(SegmentSet *p, VectorXYZ point,int *nSeg);
- static int SegmentSetNext(
- SegmentSet *pSet,
- Segment *pAB,
- int backwards,
- Segment **ppSeg, /* OUT: First segment clockwise from xR,yR->xV,yV */
- int *pfBack, /* OUT: True if output segment goes backwards */
- int *pfBend, /* OUT: Bend direction */
- double *pfAngle
- );
- static void SegmentSet_ClearFaceEdgeCache(SegmentSet *pSet);
- static void FaceBoundary_Mark_Degenerate(FaceBoundary *pFace,int code);
- static int SegmentSet_BuildFaceEdgeCache_ExpandRight(SegmentSet *pSet,int faceid,int stage);
- static void SegmentSet_BuildFaceEdgeCache(SegmentSet *pSet);
- static int OOMethod_SegmentSet_segment_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_SegmentSet_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_modified(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_count(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_bbox(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_add(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_add_virtual(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_polygon_add(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_vertex_add(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_cleanup(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_cleanup_looseend(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_edge_connection(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_check_intersecting(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_check_coincident(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_linelineintersect(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_coincident(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_find(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_vertex_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_next(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_check_oblique(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_check_looseends(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_fix_looseends(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_grid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_coords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_segment_uvcoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_selfcheck(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_uv_transform(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_polygons_xyz(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_polygons(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_polygon_faces(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SegmentSet_polygon_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int SegmentSet_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/segset.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/shapes.tcl generate-cfile-header */
- static int TclCmd_shapes_corners(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_drawobj_orientation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_poly_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_poly_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_polygon_to_vectors(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_rectangle_as_polygon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_rectangle_as_vectors(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_vector_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_hexagon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_shapes_canvas(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/shapes.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/plotter.tcl generate-cfile-header */
- static void Plotter_Delete(ClientData clientData);
- static int Plotter_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- );
- static inline double Plotter_xCanvasToActual(Plotter *p,double cx);
- static inline double Plotter_yCanvasToActual(Plotter *p,double cy);
- static inline double Plotter_xActualToCanvas(Plotter *p,double ax);
- static inline double Plotter_yActualToCanvas(Plotter *p,double ay);
- static int OOMethod_Plotter_actualcoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Plotter_canvascoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Plotter_centerset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Plotter_xoffset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Plotter_yoffset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Plotter_zoom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Plotter_constructor(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int Plotter_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/plotter.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/slicer.tcl generate-cfile-header */
- static void Slicer_Delete(ClientData clientData);
- static int Slicer_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- );
- static double Slicer_xCanvasToActual(Slicer *p,struct OneSlice *pS, double cx);
- static double Slicer_yCanvasToActual(Slicer *p,struct OneSlice *pS, double cy);
- static double Slicer_xActualToCanvas(Slicer *p,struct OneSlice *pS, double ax);
- static double Slicer_yActualToCanvas(Slicer *p,struct OneSlice *pS, double ay);
- static double Slicer_deckHeight(struct OneSlice *p, double rX);
- static struct OneSlice *Slicer_deckAt(Slicer *p, double rX, double rZ);
- static struct OneSlice *Slicer_deckAbove(Slicer *p, struct OneSlice *pRef);
- static struct OneSlice *Slicer_deckBelow(Slicer *p, struct OneSlice *pRef);
- static void Slicer_computeTopAndBottom(Slicer *p);
- static int Slicer_getDeck(
- Tcl_Interp *interp, /* Put error messages here */
- Slicer *p, /* The slicer */
- double rX, /* X coord used to find deck if pObj is a Z coord */
- Tcl_Obj *pObj, /* Either a deck name or a Z coordinate */
- struct OneSlice **ppS /* Write the slice pointer here */
- );
- static int Slicer_getDeckId(
- Tcl_Interp *interp, /* Put error messages here */
- Slicer *p, /* The slicer */
- Tcl_Obj *pObj, /* Either a deck name or a Z coordinate */
- struct OneSlice **ppS /* Write the slice pointer here */
- );
- static inline struct OneSlice *Slicer_getDeck_FromInt(
- Slicer *p,
- int did
- );
- static int slicer_drawline_do(
- Tcl_Interp *interp,
- Slicer *p,
- int coord_count,
- int *deckCoord,double *xCoord,double *yCoord,
- struct OneSlice **apDeck,
- Tcl_Obj *canvas,
- const char *zKTag,
- const char *zXTag,
- const char *zBTag
- );
- static inline double Slicer_Location_zabs(Slicer *p,struct OneSlice *pS,double x0,double dheight);
- static inline double Location_zdeck(Slicer *p,struct OneSlice *pS,double x0,double dheight);
- static int OOMethod_Slicer_drawline(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_above(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_below(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_deckid_to_name(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_deckname_to_id(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_bbox_to_location(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_bbox_to_midpoint(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_xyz_to_location(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_location_to_xyz(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_location_z(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_distance(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_actualcoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_canvascoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_deck_at_xyz(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_deckid_at_xyx(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_makedlist(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_find(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_finddid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_flatheight(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_headroom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_ceiling(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_height(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_deckheight(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_profile(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_xoffset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_zoom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_upper_height(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Slicer_Slicer_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int Slicer_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/slicer.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/wallset.tcl generate-cfile-header */
- static void Wallset_Delete(ClientData clientData);
- static int Wallset_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- );
- static int OOMethod_Wallset_atvertex(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_boundary(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_closure(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_closure_polygon(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_closure_check(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_comptlist(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_corners(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_firstboundary(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_foreach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_rawinfo(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_insert(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_primary(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_intersect(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_left(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_looseends(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_nearest(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_nextcwwall(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_right(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_selfcheck(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_zoom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_Wallset_constructor(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int Wallset_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/wallset.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/faceset.tcl generate-cfile-header */
- static PolygonHullVertex *PolygonHullVertex_ById(PolygonHull *pHull, int id);
- static PolygonHullVertex *PolygonHullVertex_ByCoords(PolygonHull *pHull, VectorXYZ A);
- static PolygonHullVertex *PolygonHullVertex_Create(
- PolygonHull *pHull,
- int id,
- VectorXYZ point
- );
- static void PolygonHullVertex_Remove(PolygonHullVertex *pVertex);
- static const char *PolygonHullFace_VertexInject(PolygonHullFace *pFace,PolygonHullVertex *pThisVertex);
- static PolygonHullFace *PolygonHullFace_Create(
- PolygonHull *pHull,
- int id
- );
- static PolygonHullFace *PolygonHull_mergeFaceList(PolygonHullFace *a, PolygonHullFace *b);
- static PolygonHullFace *PolygonHull_sortFaceList(PolygonHullFace *pList);
- static PolygonHullFace *PolygonHullFace_ById(PolygonHull *pHull, int id);
- static int PolygonHull_findFace(
- Tcl_Interp *interp, /* Leave any error message here */
- PolygonHull *pHull,
- Tcl_Obj *pObj, /* The PolygonHullFace ID */
- PolygonHullFace **ppHullFace /* Write PolygonHullFace pointer here */
- );
- static void PolygonHullFace_Remove(PolygonHullFace *pFace);
- static void PolygonHullFace_SerializeEdges(PolygonHullFace *p);
- static void PolygonHullFace_Compute(PolygonHullFace *pFace);
- static double PolygonHull_sqrDistPointToEdge(
- VectorXYZ A, VectorXYZ B, /* End points of the line segment */
- VectorXYZ X /* The point to measure distance to */
- );
- static double PolygonHull_intersectLineSegFace(
- PolygonHullFace *pFace, /* The triangle we are trying to intersect */
- VectorXYZ pStart, /* Start of the line segment */
- VectorXYZ pEnd, /* End of the line segment */
- VectorXYZ pIntersect /* Point of intersection written here if not NULL */
- );
- static PolygonHullFace *PolygonHullFace_findHits(PolygonHull *pHull, VectorXYZ A, VectorXYZ B);
- static double PolygonHull_closestPointOnFace(PolygonHullFace *p, VectorXYZ X, VectorXYZ R);
- static PolygonHullFace *PolygonHullFace_findClosest(PolygonHull *pHull,VectorXYZ X, VectorXYZ R, double *pDist);
- static PolygonHullVolume *PolygonHullVolume_ById(PolygonHull *pHull, int id);
- static PolygonHullVolume *PolygonHullVolume_Create(
- PolygonHull *pHull,
- int id
- );
- static void PolygonHullVolume_Unlink(PolygonHullVolume *pVolume);
- static void PolygonHull_clearSurfaces(PolygonHull *pHull);
- static void PolygonHull_Reset(PolygonHull *pHull);
- static void PolygonHull_Delete(ClientData clientData);
- static int PolygonHull_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- );
- static int OOMethod_PolygonHull_vertex_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_vertex_coords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_vertex_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_vertex_idlist(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_vertex_inject(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_vertex_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_vertex_at(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_exists(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_active(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_center(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_polygon(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_vertices(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_intersect(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_nearest(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_radius(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_normal(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_side(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_volume(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_faces_at(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_face_within(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_volume_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_volume_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_volume_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_volume_faces(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_volume_group(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_volume_center(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_PolygonHull_PolygonHull_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int PolygonHull_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/faceset.tcl generate-cfile-header */
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/module.ini generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/listcmd/listcmd.tcl generate-cfile-header */
- static int TclCmd_get(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_list_to_int(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_ladd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_ldelete(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/listcmd/listcmd.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/logicset/logicset.tcl generate-cfile-header */
- #define UCHAR(c) ((unsigned char) (c))
- #define TclFormatInt(buf, n) sprintf((buf), "%ld", (long)(n))
- #define MEM_DEBUG 0
- /*
- * Macros used to cast between pointers and integers (e.g. when storing an int
- * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
- * to/from pointer from/to integer of different size".
- */
- #if !defined(INT2PTR) && !defined(PTR2INT)
- # if defined(HAVE_INTPTR_T) || defined(intptr_t)
- # define INT2PTR(p) ((void *)(intptr_t)(p))
- # define PTR2INT(p) ((int)(intptr_t)(p))
- # else
- # define INT2PTR(p) ((void *)(p))
- # define PTR2INT(p) ((int)(p))
- # endif
- #endif
- #if !defined(UINT2PTR) && !defined(PTR2UINT)
- # if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
- # define UINT2PTR(p) ((void *)(uintptr_t)(p))
- # define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
- # else
- # define UINT2PTR(p) ((void *)(p))
- # define PTR2UINT(p) ((unsigned int)(p))
- # endif
- #endif
- #define VERSION "1.0"
- /*
- ** Internal call required for munging integers
- */
- #ifndef _TCLINT
- /*
- * The structure used as the internal representation of Tcl list objects. This
- * struct is grown (reallocated and copied) as necessary to hold all the
- * list's element pointers. The struct might contain more slots than currently
- * used to hold all element pointers. This is done to make append operations
- * faster.
- *
- * We only need this when compiling as a seperate library from tcl
- */
- typedef struct List {
- int refCount;
- int maxElemCount; /* Total number of element array slots. */
- int elemCount; /* Current number of list elements. */
- int canonicalFlag; /* Set if the string representation was
- * derived from the list representation. May
- * be ignored if there is no string rep at
- * all.*/
- Tcl_Obj *elements; /* First list element; the struct is grown to
- * accomodate all elements. */
- } List;
- #endif
- /*
- * During execution of the "lsort" command, structures of the following type
- * are used to arrange the objects being sorted into a collection of linked
- * lists.
- */
- typedef struct SortElement {
- union {
- char *strValuePtr;
- long intValue;
- double doubleValue;
- Tcl_Obj *objValuePtr;
- } index;
- Tcl_Obj *objPtr; /* Object being sorted, or its index. */
- struct SortElement *nextPtr;/* Next element in the list, or NULL for end
- * of list. */
- } SortElement;
- typedef struct SortInfo {
- int isIncreasing; /* Nonzero means sort in increasing order. */
- int sortMode; /* The sort mode. One of SORTMODE_* values * defined below. */
- Tcl_Obj *compareCmdPtr; /* The Tcl comparison command when sortMode is
- * SORTMODE_COMMAND. Pre-initialized to hold
- * base of command. */
- int *indexv; /* If the -index option was specified, this
- * holds the indexes contained in the list
- *
- * supplied as an argument to that option.
- * NULL if no indexes supplied, and points to
- * singleIndex field when only one
- * supplied.
- */
- int indexc; /* Number of indexes in indexv array. */
- int singleIndex; /* Static space for common index case. */
- int unique;
- int numElements;
- Tcl_Interp *interp; /* The interpreter in which the sort is being
- * done.
- */
- int resultCode; /* Completion code for the lsort command. If
- * an error occurs during the sort this is
- * changed from TCL_OK to TCL_ERROR. */
- } SortInfo;
- /*
- * These function pointer types are used with the "lsearch" and "lsort"
- * commands to facilitate the "-nocase" option.
- */
- typedef int (*SortStrCmpFn_t) (const char *, const char *);
- typedef int (*SortMemCmpFn_t) (const void *, const void *, size_t);
- /*
- * The "lsort" command needs to pass certain information down to the function
- * that compares two list elements, and the comparison function needs to pass
- * success or failure information back up to the top-level "lsort" command.
- * The following structure is used to pass this information.
- */
- /*
- * The "sortMode" field of the SortInfo structure can take on any of the
- * following values.
- */
- #define SORTMODE_ASCII 0
- #define SORTMODE_INTEGER 1
- #define SORTMODE_REAL 2
- #define SORTMODE_COMMAND 3
- #define SORTMODE_DICTIONARY 4
- #define SORTMODE_ASCII_NC 8
- /*
- * Magic values for the index field of the SortInfo structure. Note that the
- * index "end-1" will be translated to SORTIDX_END-1, etc.
- */
- #define SORTIDX_NONE -1 /* Not indexed; use whole value. */
- #define SORTIDX_END -2 /* Indexed from end. */
- /*
- * Forward declarations for procedures defined in this file:
- */
- static int DictionaryCompare(char *left, char *right);
- static SortElement * MergeLists(SortElement *leftPtr, SortElement *rightPtr,
- SortInfo *infoPtr);
- static int SortCompare(SortElement *firstPtr, SortElement *second,
- SortInfo *infoPtr);
- static Tcl_Obj *Odie_MergeList_ToObj(SortElement *elementPtr);
- static int TclCmd_logicset_union(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_contains(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_empty(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_expr_and(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_expr_or(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_product_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_product_union(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_product_xor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_product_missing(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_logicset_remove(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/logicset/logicset.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/literal/literal.tcl generate-cfile-header */
- /*
- ** constant.c
- ** Series of routines to minimize memory usage through the use
- ** of shared strings
- */
- static Tcl_HashTable OdieLiteralStringTable;
- static Tcl_Obj *OdieStatic[14];
- static unsigned int nOdieObjString = 0;
- static unsigned int nOdieHashTable = 0;
- static unsigned int nOdieHashTableCreated = 0;
- static unsigned int nOdieHashTableDeleted = 0;
- static unsigned int nOdieDictSpecCount = 0;
- static unsigned int nOdieDictSpecCreated = 0;
- static unsigned int nOdieDictSpecDeleted = 0;
- static unsigned int nOdieDictSpecShared = 0;
- static unsigned int nOdieDictSpecNull = 0;
- static unsigned int nOdieDictSpecRecycled = 0;
- static unsigned int nOdieDictSpecModified = 0;
- static unsigned int nOdieDictSpecAccessed = 0;
- static int OdieTrace=0;
- typedef struct constObj {
- char *string;
- Tcl_Obj *tclobj;
- } constObj;
- static Tcl_Obj *Odie_constant(const char *zName,int create);
- static void Odie_constant_inject(Tcl_Obj *value);
- static int TclCmd_literal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_literal_dump(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_literal_stats(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_constant_string(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/literal/literal.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/module.ini generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/param.tcl generate-cfile-header */
- Tcl_Interp *local_interp = NULL;
- Simulator *CurrentSim = NULL;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/param.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/location.tcl generate-cfile-header */
- static int TclCmd_location_grid_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_gridhash_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_location_gridhash(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_grid_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_gridhash_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_gridhash_adjacent(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_object(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- static int TclCmd_location_match(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/location.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl generate-cfile-header */
- static int OOMethod_Simulator_C_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int Simulator_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/entity.tcl generate-cfile-header */
- #define CSTRUCT_agent 1
- #define CSTRUCT_compartment 2
- #define CSTRUCT_crew 3
- #define CSTRUCT_entity 4
- #define CSTRUCT_objective 5
- #define CSTRUCT_portal 6
- #define CSTRUCT_routecompartment 7
- #define CSTRUCT_routeportal 8
- #define CSTRUCT_simlink 9
- #define CSTRUCT_simnode 10
- #define CSTRUCT_simulator 11
- #define CSTRUCT_Count 11
- #define CSTRUCT_ENTITY_AliasCount 19
- #define ENTITY_ACTIVE_NULL 0 /* Not Checked */
- #define ENTITY_ACTIVE_SHOW 1 /* Mark Checked */
- #define ENTITY_ACTIVE_HIDE 2 /* Marked Hidden */
- #define ENTITY_CLASS_AGENT a /* Agent */
- #define ENTITY_CLASS_COMPARTMENT c /* Compartment */
- #define ENTITY_CLASS_EQUIPMENT e /* Equipment */
- #define ENTITY_CLASS_LINK l /* Conduit, Cable or Link */
- #define ENTITY_CLASS_MATERIAL m /* Material */
- #define ENTITY_CLASS_PORTAL p /* Portal */
- #define ENTITY_CLASS_ROLLUP r /* Deactivation Rollup */
- #define ENTITY_CLASS_HUMAN v /* Human */
- #define ENTITY_CLASS_WALL w /* Wall Type */
- #define ENTITY_CLASS_TREE x /* Type Tree Branch */
- #define ENTITY_CLASS_GENERIC y /* Generic Type */
- #define CSTRUCT_ENTITY_ACTIVE 0
- #define CSTRUCT_ENTITY_CHANGED 1
- #define CSTRUCT_ENTITY_CLASS 2
- #define CSTRUCT_ENTITY_DRAWN 3
- #define CSTRUCT_ENTITY_GROUPID 4
- #define CSTRUCT_ENTITY_HIDDEN 5
- #define CSTRUCT_ENTITY_HIGHLIGHT 6
- #define CSTRUCT_ENTITY_IS_TYPE 7
- #define CSTRUCT_ENTITY_MOVED 8
- #define CSTRUCT_ENTITY_NCHILD 9
- #define CSTRUCT_ENTITY_ONCOUNT 10
- #define CSTRUCT_ENTITY_OPEN 11
- #define CSTRUCT_ENTITY_PARENT 12
- #define CSTRUCT_ENTITY_REDRAW 13
- #define CSTRUCT_ENTITY_REPAINT 14
- #define CSTRUCT_ENTITY_SYNTHETIC 15
- #define CSTRUCT_ENTITY_TRACE 16
- #define CSTRUCT_ENTITY_VISIBLE 17
- #define CSTRUCT_ENTITY_Count 18
- static int OOMethod_OOEntity_C_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_attach_to(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_compartment(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_comptid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_count(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_deckid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_drawn_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_exists(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_for(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_foreach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_groupid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_groups_recalculate(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_hidden_inherit(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_location(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_midpoint(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_nodeget(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_nodeput(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_nodewith(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_normalize(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_orientation(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_redraw(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_setting(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_spec_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_spec_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_spec_replace(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_struct_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_struct_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_type(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_typeid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_visible(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_visible_filter(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_visible_hidden_subtract(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_visible_inherit(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_visible_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_visible_tree(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_OOEntity_witheach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOEntity_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/entity.tcl generate-cfile-header */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simtype.tcl generate-cfile-header */
- static int OOMethod_SimType_C_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_children(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_count(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_exists(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_for(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_foreach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_groupid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_nodeget(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_nodeput(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_nodewith(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_normalize(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_parent(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_setting(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_spec_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_spec_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_spec_replace(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_struct_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_struct_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_type(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_typeid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_visible_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int OOMethod_SimType_witheach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv);
- static int SimType_OO_Init(Tcl_Interp *interp);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simtype.tcl generate-cfile-header */
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/module.ini generate-cfile-header */
- /* END generate-cfile-header */
- /* BEGIN generate-cfile-constant */
- const static Tcl_ObjectMetadataType LinkDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Link",
- NULL,
- NULL
- };
- #define GETLINK(OBJCONTEXT) (Link *) Tcl_ObjectGetMetadata(OBJCONTEXT,&LinkDataType)
- const static Tcl_ObjectMetadataType HashDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Hash",
- NULL,
- NULL
- };
- #define GETHASH(OBJCONTEXT) (Hash *) Tcl_ObjectGetMetadata(OBJCONTEXT,&HashDataType)
- const static Tcl_ObjectMetadataType HashElemDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "HashElem",
- NULL,
- NULL
- };
- #define GETHASHELEM(OBJCONTEXT) (HashElem *) Tcl_ObjectGetMetadata(OBJCONTEXT,&HashElemDataType)
- const static Tcl_ObjectMetadataType Odie_MatrixObjDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Odie_MatrixObj",
- NULL,
- NULL
- };
- #define GETODIE_MATRIXOBJ(OBJCONTEXT) (Odie_MatrixObj *) Tcl_ObjectGetMetadata(OBJCONTEXT,&Odie_MatrixObjDataType)
- const static Tcl_ObjectMetadataType MatrixFormDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "MatrixForm",
- NULL,
- NULL
- };
- #define GETMATRIXFORM(OBJCONTEXT) (MatrixForm *) Tcl_ObjectGetMetadata(OBJCONTEXT,&MatrixFormDataType)
- const Tcl_ObjType matrix_tclobjtype = {
- .name="matrix",
- .freeIntRepProc = &MatrixObj_freeIntRepProc,
- .dupIntRepProc = &MatrixObj_dupIntRepProc,
- .updateStringProc = &MatrixObj_updateStringProc,
- .setFromAnyProc = &MatrixObj_setFromAnyProc
- };
- const static Tcl_ObjectMetadataType TriagPointDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "TriagPoint",
- NULL,
- NULL
- };
- #define GETTRIAGPOINT(OBJCONTEXT) (TriagPoint *) Tcl_ObjectGetMetadata(OBJCONTEXT,&TriagPointDataType)
- const static Tcl_ObjectMetadataType TriagSegmentDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "TriagSegment",
- NULL,
- NULL
- };
- #define GETTRIAGSEGMENT(OBJCONTEXT) (TriagSegment *) Tcl_ObjectGetMetadata(OBJCONTEXT,&TriagSegmentDataType)
- const static Tcl_ObjectMetadataType TriagSegSetDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "TriagSegSet",
- NULL,
- NULL
- };
- #define GETTRIAGSEGSET(OBJCONTEXT) (TriagSegSet *) Tcl_ObjectGetMetadata(OBJCONTEXT,&TriagSegSetDataType)
- const static Tcl_ObjectMetadataType Odie_PolygonDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Odie_Polygon",
- NULL,
- NULL
- };
- #define GETODIE_POLYGON(OBJCONTEXT) (Odie_Polygon *) Tcl_ObjectGetMetadata(OBJCONTEXT,&Odie_PolygonDataType)
- const Tcl_ObjType polygon_tclobjtype = {
- .name="polygon",
- .freeIntRepProc = &PolygonObj_freeIntRepProc,
- .dupIntRepProc = &PolygonObj_dupIntRepProc,
- .updateStringProc = &PolygonObj_updateStringRepProc,
- .setFromAnyProc = &PolygonObj_setFromAnyProc
- };
- const static Tcl_ObjectMetadataType Odie_FaceXYZDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Odie_FaceXYZ",
- NULL,
- NULL
- };
- #define GETODIE_FACEXYZ(OBJCONTEXT) (Odie_FaceXYZ *) Tcl_ObjectGetMetadata(OBJCONTEXT,&Odie_FaceXYZDataType)
- const Tcl_ObjType odie_polygon_tclobjtype = {
- .name="odie_polygon",
- .freeIntRepProc = &Odie_FaceXYZ_freeIntRepProc,
- .dupIntRepProc = &Odie_FaceXYZ_dupIntRepProc,
- .updateStringProc = &Odie_FaceXYZ_updateStringProc,
- .setFromAnyProc = &Odie_FaceXYZ_setFromAnyProc
- };
- const static Tcl_ObjectMetadataType FaceBoundaryDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "FaceBoundary",
- NULL,
- NULL
- };
- #define GETFACEBOUNDARY(OBJCONTEXT) (FaceBoundary *) Tcl_ObjectGetMetadata(OBJCONTEXT,&FaceBoundaryDataType)
- const static Tcl_ObjectMetadataType SegmentDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Segment",
- NULL,
- NULL
- };
- #define GETSEGMENT(OBJCONTEXT) (Segment *) Tcl_ObjectGetMetadata(OBJCONTEXT,&SegmentDataType)
- const static Tcl_ObjectMetadataType SegmentSetDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "SegmentSet",
- SegmentSet_Delete,
- SegmentSet_Clone
- };
- #define GETSEGMENTSET(OBJCONTEXT) (SegmentSet *) Tcl_ObjectGetMetadata(OBJCONTEXT,&SegmentSetDataType)
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_info = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_info",
- .callProc = OOMethod_SegmentSet_segment_info,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_SegmentSet_Init = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "SegmentSet_Init",
- .callProc = OOMethod_SegmentSet_SegmentSet_Init,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_modified = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "modified",
- .callProc = OOMethod_SegmentSet_modified,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_count = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_count",
- .callProc = OOMethod_SegmentSet_segment_count,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_bbox = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "bbox",
- .callProc = OOMethod_SegmentSet_bbox,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_reset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_reset",
- .callProc = OOMethod_SegmentSet_segment_reset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_add = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_add",
- .callProc = OOMethod_SegmentSet_segment_add,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_add_virtual = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_add_virtual",
- .callProc = OOMethod_SegmentSet_segment_add_virtual,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_polygon_add = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "polygon_add",
- .callProc = OOMethod_SegmentSet_polygon_add,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_vertex_add = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_add",
- .callProc = OOMethod_SegmentSet_vertex_add,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_delete",
- .callProc = OOMethod_SegmentSet_segment_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "delete",
- .callProc = OOMethod_SegmentSet_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_cleanup = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "cleanup",
- .callProc = OOMethod_SegmentSet_cleanup,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_cleanup_looseend = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "cleanup_looseend",
- .callProc = OOMethod_SegmentSet_cleanup_looseend,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_edge_connection = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "edge_connection",
- .callProc = OOMethod_SegmentSet_edge_connection,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_check_intersecting = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "check_intersecting",
- .callProc = OOMethod_SegmentSet_check_intersecting,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_check_coincident = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "check_coincident",
- .callProc = OOMethod_SegmentSet_check_coincident,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_linelineintersect = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_linelineintersect",
- .callProc = OOMethod_SegmentSet_segment_linelineintersect,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_coincident = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_coincident",
- .callProc = OOMethod_SegmentSet_segment_coincident,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_find = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_find",
- .callProc = OOMethod_SegmentSet_segment_find,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_vertex_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_delete",
- .callProc = OOMethod_SegmentSet_vertex_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_next = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_next",
- .callProc = OOMethod_SegmentSet_segment_next,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_check_oblique = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "check_oblique",
- .callProc = OOMethod_SegmentSet_check_oblique,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_check_looseends = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "check_looseends",
- .callProc = OOMethod_SegmentSet_check_looseends,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_fix_looseends = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "fix_looseends",
- .callProc = OOMethod_SegmentSet_fix_looseends,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_grid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "grid",
- .callProc = OOMethod_SegmentSet_grid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_list",
- .callProc = OOMethod_SegmentSet_segment_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_coords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_coords",
- .callProc = OOMethod_SegmentSet_segment_coords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_segment_uvcoords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "segment_uvcoords",
- .callProc = OOMethod_SegmentSet_segment_uvcoords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_selfcheck = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "selfcheck",
- .callProc = OOMethod_SegmentSet_selfcheck,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_uv_transform = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "uv_transform",
- .callProc = OOMethod_SegmentSet_uv_transform,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_polygons_xyz = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "polygons_xyz",
- .callProc = OOMethod_SegmentSet_polygons_xyz,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_polygons = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "polygons",
- .callProc = OOMethod_SegmentSet_polygons,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_polygon_faces = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "polygon_faces",
- .callProc = OOMethod_SegmentSet_polygon_faces,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SegmentSet_polygon_info = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "polygon_info",
- .callProc = OOMethod_SegmentSet_polygon_info,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_ObjectMetadataType PlotterDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Plotter",
- Plotter_Delete,
- Plotter_Clone
- };
- #define GETPLOTTER(OBJCONTEXT) (Plotter *) Tcl_ObjectGetMetadata(OBJCONTEXT,&PlotterDataType)
- const static Tcl_MethodType OOMethodType_Plotter_actualcoords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "actualcoords",
- .callProc = OOMethod_Plotter_actualcoords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Plotter_canvascoords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "canvascoords",
- .callProc = OOMethod_Plotter_canvascoords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Plotter_centerset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "centerset",
- .callProc = OOMethod_Plotter_centerset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Plotter_xoffset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "xoffset",
- .callProc = OOMethod_Plotter_xoffset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Plotter_yoffset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "yoffset",
- .callProc = OOMethod_Plotter_yoffset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Plotter_zoom = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "zoom",
- .callProc = OOMethod_Plotter_zoom,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Plotter_constructor = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "constructor",
- .callProc = OOMethod_Plotter_constructor,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_ObjectMetadataType OneSliceDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "OneSlice",
- NULL,
- NULL
- };
- #define GETONESLICE(OBJCONTEXT) (OneSlice *) Tcl_ObjectGetMetadata(OBJCONTEXT,&OneSliceDataType)
- const static Tcl_ObjectMetadataType SlicerDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Slicer",
- Slicer_Delete,
- Slicer_Clone
- };
- #define GETSLICER(OBJCONTEXT) (Slicer *) Tcl_ObjectGetMetadata(OBJCONTEXT,&SlicerDataType)
- const static Tcl_MethodType OOMethodType_Slicer_drawline = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "drawline",
- .callProc = OOMethod_Slicer_drawline,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_above = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "above",
- .callProc = OOMethod_Slicer_above,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_below = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "below",
- .callProc = OOMethod_Slicer_below,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_deckid_to_name = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "deckid_to_name",
- .callProc = OOMethod_Slicer_deckid_to_name,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_deckname_to_id = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "deckname_to_id",
- .callProc = OOMethod_Slicer_deckname_to_id,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_bbox_to_location = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "bbox_to_location",
- .callProc = OOMethod_Slicer_bbox_to_location,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_bbox_to_midpoint = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "bbox_to_midpoint",
- .callProc = OOMethod_Slicer_bbox_to_midpoint,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_xyz_to_location = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "xyz_to_location",
- .callProc = OOMethod_Slicer_xyz_to_location,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_location_to_xyz = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "location_to_xyz",
- .callProc = OOMethod_Slicer_location_to_xyz,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_location_z = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "location_z",
- .callProc = OOMethod_Slicer_location_z,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_distance = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "distance",
- .callProc = OOMethod_Slicer_distance,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_actualcoords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "actualcoords",
- .callProc = OOMethod_Slicer_actualcoords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_canvascoords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "canvascoords",
- .callProc = OOMethod_Slicer_canvascoords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_create = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "create",
- .callProc = OOMethod_Slicer_create,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_deck_at_xyz = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "deck_at_xyz",
- .callProc = OOMethod_Slicer_deck_at_xyz,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_deckid_at_xyx = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "deckid_at_xyx",
- .callProc = OOMethod_Slicer_deckid_at_xyx,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "delete",
- .callProc = OOMethod_Slicer_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_makedlist = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "makedlist",
- .callProc = OOMethod_Slicer_makedlist,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_find = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "find",
- .callProc = OOMethod_Slicer_find,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_finddid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "finddid",
- .callProc = OOMethod_Slicer_finddid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_flatheight = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "flatheight",
- .callProc = OOMethod_Slicer_flatheight,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_headroom = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "headroom",
- .callProc = OOMethod_Slicer_headroom,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_ceiling = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "ceiling",
- .callProc = OOMethod_Slicer_ceiling,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_height = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "height",
- .callProc = OOMethod_Slicer_height,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_deckheight = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "deckheight",
- .callProc = OOMethod_Slicer_deckheight,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_info = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "info",
- .callProc = OOMethod_Slicer_info,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "list",
- .callProc = OOMethod_Slicer_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_profile = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "profile",
- .callProc = OOMethod_Slicer_profile,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_xoffset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "xoffset",
- .callProc = OOMethod_Slicer_xoffset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_zoom = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "zoom",
- .callProc = OOMethod_Slicer_zoom,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_upper_height = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "upper_height",
- .callProc = OOMethod_Slicer_upper_height,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Slicer_Slicer_Init = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "Slicer_Init",
- .callProc = OOMethod_Slicer_Slicer_Init,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_ObjectMetadataType BoundaryDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Boundary",
- NULL,
- NULL
- };
- #define GETBOUNDARY(OBJCONTEXT) (Boundary *) Tcl_ObjectGetMetadata(OBJCONTEXT,&BoundaryDataType)
- const static Tcl_ObjectMetadataType ComptBoxDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "ComptBox",
- NULL,
- NULL
- };
- #define GETCOMPTBOX(OBJCONTEXT) (ComptBox *) Tcl_ObjectGetMetadata(OBJCONTEXT,&ComptBoxDataType)
- const static Tcl_ObjectMetadataType WallsetDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Wallset",
- Wallset_Delete,
- Wallset_Clone
- };
- #define GETWALLSET(OBJCONTEXT) (Wallset *) Tcl_ObjectGetMetadata(OBJCONTEXT,&WallsetDataType)
- const static Tcl_MethodType OOMethodType_Wallset_atvertex = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "atvertex",
- .callProc = OOMethod_Wallset_atvertex,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_boundary = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "boundary",
- .callProc = OOMethod_Wallset_boundary,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_closure = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "closure",
- .callProc = OOMethod_Wallset_closure,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_closure_polygon = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "closure_polygon",
- .callProc = OOMethod_Wallset_closure_polygon,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_closure_check = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "closure_check",
- .callProc = OOMethod_Wallset_closure_check,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_comptlist = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "comptlist",
- .callProc = OOMethod_Wallset_comptlist,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_corners = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "corners",
- .callProc = OOMethod_Wallset_corners,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "delete",
- .callProc = OOMethod_Wallset_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_firstboundary = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "firstboundary",
- .callProc = OOMethod_Wallset_firstboundary,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_foreach = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "foreach",
- .callProc = OOMethod_Wallset_foreach,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_info = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "info",
- .callProc = OOMethod_Wallset_info,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_rawinfo = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "rawinfo",
- .callProc = OOMethod_Wallset_rawinfo,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_insert = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "insert",
- .callProc = OOMethod_Wallset_insert,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_primary = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "primary",
- .callProc = OOMethod_Wallset_primary,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_intersect = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "intersect",
- .callProc = OOMethod_Wallset_intersect,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_left = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "left",
- .callProc = OOMethod_Wallset_left,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "list",
- .callProc = OOMethod_Wallset_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_looseends = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "looseends",
- .callProc = OOMethod_Wallset_looseends,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_nearest = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nearest",
- .callProc = OOMethod_Wallset_nearest,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_nextcwwall = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nextcwwall",
- .callProc = OOMethod_Wallset_nextcwwall,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_right = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "right",
- .callProc = OOMethod_Wallset_right,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_selfcheck = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "selfcheck",
- .callProc = OOMethod_Wallset_selfcheck,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_zoom = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "zoom",
- .callProc = OOMethod_Wallset_zoom,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_Wallset_constructor = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "constructor",
- .callProc = OOMethod_Wallset_constructor,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_ObjectMetadataType PolygonHullVertexDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "PolygonHullVertex",
- NULL,
- NULL
- };
- #define GETPOLYGONHULLVERTEX(OBJCONTEXT) (PolygonHullVertex *) Tcl_ObjectGetMetadata(OBJCONTEXT,&PolygonHullVertexDataType)
- const static Tcl_ObjectMetadataType PolygonHullFaceDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "PolygonHullFace",
- NULL,
- NULL
- };
- #define GETPOLYGONHULLFACE(OBJCONTEXT) (PolygonHullFace *) Tcl_ObjectGetMetadata(OBJCONTEXT,&PolygonHullFaceDataType)
- const static Tcl_ObjectMetadataType PolygonHullVolumeDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "PolygonHullVolume",
- NULL,
- NULL
- };
- #define GETPOLYGONHULLVOLUME(OBJCONTEXT) (PolygonHullVolume *) Tcl_ObjectGetMetadata(OBJCONTEXT,&PolygonHullVolumeDataType)
- const static Tcl_ObjectMetadataType PolygonHullDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "PolygonHull",
- PolygonHull_Delete,
- PolygonHull_Clone
- };
- #define GETPOLYGONHULL(OBJCONTEXT) (PolygonHull *) Tcl_ObjectGetMetadata(OBJCONTEXT,&PolygonHullDataType)
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_create = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_create",
- .callProc = OOMethod_PolygonHull_vertex_create,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_coords = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_coords",
- .callProc = OOMethod_PolygonHull_vertex_coords,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_delete",
- .callProc = OOMethod_PolygonHull_vertex_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_idlist = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_idlist",
- .callProc = OOMethod_PolygonHull_vertex_idlist,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_inject = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_inject",
- .callProc = OOMethod_PolygonHull_vertex_inject,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_list",
- .callProc = OOMethod_PolygonHull_vertex_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_vertex_at = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "vertex_at",
- .callProc = OOMethod_PolygonHull_vertex_at,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_info = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_info",
- .callProc = OOMethod_PolygonHull_face_info,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_exists = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_exists",
- .callProc = OOMethod_PolygonHull_face_exists,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_active = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_active",
- .callProc = OOMethod_PolygonHull_face_active,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_center = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_center",
- .callProc = OOMethod_PolygonHull_face_center,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_polygon = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_polygon",
- .callProc = OOMethod_PolygonHull_face_polygon,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_vertices = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_vertices",
- .callProc = OOMethod_PolygonHull_face_vertices,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_create = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_create",
- .callProc = OOMethod_PolygonHull_face_create,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_delete",
- .callProc = OOMethod_PolygonHull_face_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_intersect = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_intersect",
- .callProc = OOMethod_PolygonHull_face_intersect,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_list",
- .callProc = OOMethod_PolygonHull_face_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_nearest = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_nearest",
- .callProc = OOMethod_PolygonHull_face_nearest,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_radius = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_radius",
- .callProc = OOMethod_PolygonHull_face_radius,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_normal = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_normal",
- .callProc = OOMethod_PolygonHull_face_normal,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_side = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_side",
- .callProc = OOMethod_PolygonHull_face_side,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_volume = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_volume",
- .callProc = OOMethod_PolygonHull_face_volume,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_faces_at = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "faces_at",
- .callProc = OOMethod_PolygonHull_faces_at,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_face_within = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "face_within",
- .callProc = OOMethod_PolygonHull_face_within,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_volume_create = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "volume_create",
- .callProc = OOMethod_PolygonHull_volume_create,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_volume_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "volume_delete",
- .callProc = OOMethod_PolygonHull_volume_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_volume_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "volume_list",
- .callProc = OOMethod_PolygonHull_volume_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_volume_faces = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "volume_faces",
- .callProc = OOMethod_PolygonHull_volume_faces,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_volume_group = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "volume_group",
- .callProc = OOMethod_PolygonHull_volume_group,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_volume_center = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "volume_center",
- .callProc = OOMethod_PolygonHull_volume_center,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_reset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "reset",
- .callProc = OOMethod_PolygonHull_reset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_PolygonHull_PolygonHull_Init = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "PolygonHull_Init",
- .callProc = OOMethod_PolygonHull_PolygonHull_Init,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_ObjectMetadataType Odie_ObjDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Odie_Obj",
- NULL,
- NULL
- };
- #define GETODIE_OBJ(OBJCONTEXT) (Odie_Obj *) Tcl_ObjectGetMetadata(OBJCONTEXT,&Odie_ObjDataType)
- const static Tcl_ObjectMetadataType entityObjDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "entityObj",
- NULL,
- NULL
- };
- #define GETENTITYOBJ(OBJCONTEXT) (entityObj *) Tcl_ObjectGetMetadata(OBJCONTEXT,&entityObjDataType)
- const static Tcl_ObjectMetadataType OdieParamNameMapDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "OdieParamNameMap",
- NULL,
- NULL
- };
- #define GETODIEPARAMNAMEMAP(OBJCONTEXT) (OdieParamNameMap *) Tcl_ObjectGetMetadata(OBJCONTEXT,&OdieParamNameMapDataType)
- const static Tcl_ObjectMetadataType Irm_LocationDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Irm_Location",
- NULL,
- NULL
- };
- #define GETIRM_LOCATION(OBJCONTEXT) (Irm_Location *) Tcl_ObjectGetMetadata(OBJCONTEXT,&Irm_LocationDataType)
- const static Tcl_ObjectMetadataType SimulatorDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Simulator",
- NULL,
- NULL
- };
- #define GETSIMULATOR(OBJCONTEXT) (Simulator *) Tcl_ObjectGetMetadata(OBJCONTEXT,&SimulatorDataType)
- const static Tcl_MethodType OOMethodType_Simulator_C_Init = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "C_Init",
- .callProc = OOMethod_Simulator_C_Init,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_ObjectMetadataType EntityDataType = {
- TCL_OO_METADATA_VERSION_CURRENT,
- "Entity",
- NULL,
- NULL
- };
- #define GETENTITY(OBJCONTEXT) (Entity *) Tcl_ObjectGetMetadata(OBJCONTEXT,&EntityDataType)
- const static Tcl_MethodType OOMethodType_OOEntity_C_Init = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "C_Init",
- .callProc = OOMethod_OOEntity_C_Init,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_create = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "create",
- .callProc = OOMethod_OOEntity_create,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_attach_to = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "attach_to",
- .callProc = OOMethod_OOEntity_attach_to,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_compartment = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "compartment",
- .callProc = OOMethod_OOEntity_compartment,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_comptid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "comptid",
- .callProc = OOMethod_OOEntity_comptid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_count = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "count",
- .callProc = OOMethod_OOEntity_count,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_deckid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "deckid",
- .callProc = OOMethod_OOEntity_deckid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "delete",
- .callProc = OOMethod_OOEntity_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_drawn_reset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "drawn_reset",
- .callProc = OOMethod_OOEntity_drawn_reset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_exists = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "exists",
- .callProc = OOMethod_OOEntity_exists,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_for = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "for",
- .callProc = OOMethod_OOEntity_for,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_foreach = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "foreach",
- .callProc = OOMethod_OOEntity_foreach,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_groupid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "groupid",
- .callProc = OOMethod_OOEntity_groupid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_groups_recalculate = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "groups_recalculate",
- .callProc = OOMethod_OOEntity_groups_recalculate,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_hidden_inherit = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "hidden_inherit",
- .callProc = OOMethod_OOEntity_hidden_inherit,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "list",
- .callProc = OOMethod_OOEntity_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_location = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "location",
- .callProc = OOMethod_OOEntity_location,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_midpoint = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "midpoint",
- .callProc = OOMethod_OOEntity_midpoint,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_nodeget = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nodeget",
- .callProc = OOMethod_OOEntity_nodeget,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_nodeput = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nodeput",
- .callProc = OOMethod_OOEntity_nodeput,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_nodewith = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nodewith",
- .callProc = OOMethod_OOEntity_nodewith,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_normalize = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "normalize",
- .callProc = OOMethod_OOEntity_normalize,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_orientation = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "orientation",
- .callProc = OOMethod_OOEntity_orientation,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_redraw = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "redraw",
- .callProc = OOMethod_OOEntity_redraw,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_reset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "reset",
- .callProc = OOMethod_OOEntity_reset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_setting = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "setting",
- .callProc = OOMethod_OOEntity_setting,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_spec_get = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "spec_get",
- .callProc = OOMethod_OOEntity_spec_get,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_spec_put = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "spec_put",
- .callProc = OOMethod_OOEntity_spec_put,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_spec_replace = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "spec_replace",
- .callProc = OOMethod_OOEntity_spec_replace,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_struct_get = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "struct_get",
- .callProc = OOMethod_OOEntity_struct_get,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_struct_put = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "struct_put",
- .callProc = OOMethod_OOEntity_struct_put,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_type = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "type",
- .callProc = OOMethod_OOEntity_type,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_typeid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "typeid",
- .callProc = OOMethod_OOEntity_typeid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_visible = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible",
- .callProc = OOMethod_OOEntity_visible,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_visible_filter = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible_filter",
- .callProc = OOMethod_OOEntity_visible_filter,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_visible_hidden_subtract = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible_hidden_subtract",
- .callProc = OOMethod_OOEntity_visible_hidden_subtract,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_visible_inherit = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible_inherit",
- .callProc = OOMethod_OOEntity_visible_inherit,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_visible_reset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible_reset",
- .callProc = OOMethod_OOEntity_visible_reset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_visible_tree = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible_tree",
- .callProc = OOMethod_OOEntity_visible_tree,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_OOEntity_witheach = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "witheach",
- .callProc = OOMethod_OOEntity_witheach,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_C_Init = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "C_Init",
- .callProc = OOMethod_SimType_C_Init,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_children = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "children",
- .callProc = OOMethod_SimType_children,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_count = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "count",
- .callProc = OOMethod_SimType_count,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_create = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "create",
- .callProc = OOMethod_SimType_create,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_delete = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "delete",
- .callProc = OOMethod_SimType_delete,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_exists = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "exists",
- .callProc = OOMethod_SimType_exists,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_for = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "for",
- .callProc = OOMethod_SimType_for,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_foreach = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "foreach",
- .callProc = OOMethod_SimType_foreach,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_groupid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "groupid",
- .callProc = OOMethod_SimType_groupid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_list = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "list",
- .callProc = OOMethod_SimType_list,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_nodeget = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nodeget",
- .callProc = OOMethod_SimType_nodeget,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_nodeput = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nodeput",
- .callProc = OOMethod_SimType_nodeput,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_nodewith = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "nodewith",
- .callProc = OOMethod_SimType_nodewith,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_normalize = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "normalize",
- .callProc = OOMethod_SimType_normalize,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_parent = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "parent",
- .callProc = OOMethod_SimType_parent,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_setting = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "setting",
- .callProc = OOMethod_SimType_setting,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_spec_get = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "spec_get",
- .callProc = OOMethod_SimType_spec_get,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_spec_put = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "spec_put",
- .callProc = OOMethod_SimType_spec_put,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_spec_replace = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "spec_replace",
- .callProc = OOMethod_SimType_spec_replace,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_struct_get = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "struct_get",
- .callProc = OOMethod_SimType_struct_get,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_struct_put = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "struct_put",
- .callProc = OOMethod_SimType_struct_put,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_type = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "type",
- .callProc = OOMethod_SimType_type,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_typeid = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "typeid",
- .callProc = OOMethod_SimType_typeid,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_visible_reset = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "visible_reset",
- .callProc = OOMethod_SimType_visible_reset,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- const static Tcl_MethodType OOMethodType_SimType_witheach = {
- .version = TCL_OO_METADATA_VERSION_CURRENT,
- .name = "witheach",
- .callProc = OOMethod_SimType_witheach,
- .deleteProc = NULL,
- .cloneProc = NULL
- };
- /* END generate-cfile-constant */
- /* BEGIN generate-cfile-functions */
- /* *Odie_Alloc */
- void *Odie_Alloc(unsigned int size){
- /*
- ** Provide wrappers around malloc and free
- */
- void *p;
- p=(void *)ckalloc(size);
- memset(p,0,size);
- return p;
- }
- /*
- ** Hash and comparison functions when the mode is READI_HASH_INT
- */
- static int intHash(const void *pKey, int nKey){
- return nKey ^ (nKey<<8) ^ (nKey>>8);
- }
- static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- return n2 - n1;
- }
- /*
- ** Hash and comparison functions when the mode is READI_HASH_POINTER
- */
- static int ptrHash(const void *pKey, int nKey){
- uptr x = Addr(pKey);
- return x ^ (x<<8) ^ (x>>8);
- }
- static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( pKey1==pKey2 ) return 0;
- if( pKey1<pKey2 ) return -1;
- return 1;
- }
- /*
- ** Hash and comparison functions when the mode is READI_HASH_BINARY
- */
- static int binHash(const void *pKey, int nKey){
- int h = 0;
- const char *z = (const char *)pKey;
- while( nKey-- > 0 ){
- h = (h<<3) ^ h ^ *(z++);
- }
- return h & 0x7fffffff;
- }
- static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
- if( n1!=n2 ) return n2-n1;
- return memcmp(pKey1,pKey2,n1);
- }
- /*
- ** Return a pointer to the appropriate hash function given the key class.
- **
- ** The C syntax in this function definition may be unfamilar to some
- ** programmers, so we provide the following additional explanation:
- **
- ** The name of the function is "hashFunction". The function takes a
- ** single parameter "keyClass". The return value of hashFunction()
- ** is a pointer to another function. Specifically, the return value
- ** of hashFunction() is a pointer to a function that takes two parameters
- ** with types "const void*" and "int" and returns an "int".
- */
- static int (*hashFunction(int keyClass))(const void*,int){
- switch( keyClass ){
- case READI_HASH_INT: return &intHash;
- case READI_HASH_POINTER: return &ptrHash;
- case READI_HASH_BINARY: return &binHash;;
- default: break;
- }
- return 0;
- }
- /*
- ** Return a pointer to the appropriate hash function given the key class.
- **
- ** For help in interpreted the obscure C code in the function definition,
- ** see the header comment on the previous function.
- */
- static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
- switch( keyClass ){
- case READI_HASH_INT: return &intCompare;
- case READI_HASH_POINTER: return &ptrCompare;
- case READI_HASH_BINARY: return &binCompare;
- default: break;
- }
- return 0;
- }
- /* Resize the hash table so that it cantains "new_size" buckets.
- ** "new_size" must be a power of 2. The hash table might fail
- ** to resize if Odie_Alloc() fails.
- */
- static void rehash(Hash *pH, int new_size){
- struct _ht *new_ht; /* The new hash table */
- HashElem *elem, *next_elem; /* For looping over existing elements */
- HashElem *x; /* Element being copied to new hash table */
- int (*xHash)(const void*,int); /* The hash function */
- assert( (new_size & (new_size-1))==0 );
- new_ht = (struct _ht *)Odie_Alloc( new_size*sizeof(struct _ht) );
- if( new_ht==0 ) return;
- memset(new_ht, 0, new_size*sizeof(struct _ht));
- if( pH->ht ) Odie_Free((char *)pH->ht);
- pH->ht = new_ht;
- pH->htsize = new_size;
- xHash = hashFunction(pH->keyClass);
- for(elem=pH->first, pH->first=0; elem; elem = next_elem){
- int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
- next_elem = elem->next;
- x = new_ht[h].chain;
- if( x ){
- elem->next = x;
- elem->prev = x->prev;
- if( x->prev ) x->prev->next = elem;
- else pH->first = elem;
- x->prev = elem;
- }else{
- elem->next = pH->first;
- if( pH->first ) pH->first->prev = elem;
- elem->prev = 0;
- pH->first = elem;
- }
- new_ht[h].chain = elem;
- new_ht[h].count++;
- }
- }
- /* This function (for internal use only) locates an element in an
- ** hash table that matches the given key. The hash for this key has
- ** already been computed and is passed as the 4th parameter.
- */
- static HashElem *findElementGivenHash(
- const Hash *pH, /* The pH to be searched */
- const void *pKey, /* The key we are searching for */
- int nKey,
- int h /* The hash for this key. */
- ){
- HashElem *elem; /* Used to loop thru the element list */
- int count; /* Number of elements left to test */
- int (*xCompare)(const void*,int,const void*,int); /* comparison function */
- if( pH->ht ){
- elem = pH->ht[h].chain;
- count = pH->ht[h].count;
- xCompare = compareFunction(pH->keyClass);
- while( count-- && elem ){
- if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
- return elem;
- }
- elem = elem->next;
- }
- }
- return 0;
- }
- /* Remove a single entry from the hash table given a pointer to that
- ** element and a hash on the element's key.
- */
- static void removeElementGivenHash(
- Hash *pH, /* The pH containing "elem" */
- HashElem* elem, /* The element to be removed from the pH */
- int h /* Hash value for the element */
- ){
- if( elem->prev ){
- elem->prev->next = elem->next;
- }else{
- pH->first = elem->next;
- }
- if( elem->next ){
- elem->next->prev = elem->prev;
- }
- if( pH->ht[h].chain==elem ){
- pH->ht[h].chain = elem->next;
- }
- pH->ht[h].count--;
- if( pH->ht[h].count<=0 ){
- pH->ht[h].chain = 0;
- }
- if( pH->copyKey && elem->pKey ){
- Odie_Free((char *)elem->pKey);
- }
- Odie_Free((char *) elem );
- pH->count--;
- }
- /* readiHashNoCase */
- int readiHashNoCase(const void *pKey, int nKey){
- const char *z = (const char *)pKey;
- int h = 0;
- if( nKey<=0 ) nKey = strlen(z);
- while( nKey > 0 ){
- h = (h<<3) ^ h ^ tolower(*z++);
- nKey--;
- }
- return h & 0x7fffffff;
- }
- /* readiHashInit */
- void readiHashInit(Hash *new, int keyClass, int copyKey){
- assert( new!=0 );
- assert( keyClass>=READI_HASH_INT && keyClass<=READI_HASH_BINARY );
- new->keyClass = keyClass;
- new->copyKey = copyKey && keyClass==READI_HASH_BINARY;
- new->first = 0;
- new->count = 0;
- new->htsize = 0;
- new->ht = 0;
- }
- /* readiHashClear */
- void readiHashClear(Hash *pH){
- HashElem *elem; /* For looping over all elements of the table */
- assert( pH!=0 );
- elem = pH->first;
- pH->first = 0;
- if( pH->ht ) Odie_Free((char *)pH->ht);
- pH->ht = 0;
- pH->htsize = 0;
- while( elem ){
- HashElem *next_elem = elem->next;
- if( pH->copyKey && elem->pKey ){
- Odie_Free((char *)elem->pKey);
- }
- Odie_Free((char *)elem);
- elem = next_elem;
- }
- pH->count = 0;
- }
- /* *readiHashFind */
- void *readiHashFind(const Hash *pH, const void *pKey, int nKey){
- int h; /* A hash on key */
- HashElem *elem; /* The element that matches key */
- int (*xHash)(const void*,int); /* The hash function */
- if( pH==0 || pH->ht==0 ) return 0;
- xHash = hashFunction(pH->keyClass);
- assert( xHash!=0 );
- h = (*xHash)(pKey,nKey);
- assert( (pH->htsize & (pH->htsize-1))==0 );
- elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
- return elem ? elem->data : 0;
- }
- /* *readiHashInsert */
- void *readiHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
- int hraw; /* Raw hash value of the key */
- int h; /* the hash of the key modulo hash table size */
- HashElem *elem; /* Used to loop thru the element list */
- HashElem *new_elem; /* New element added to the pH */
- int (*xHash)(const void*,int); /* The hash function */
- assert( pH!=0 );
- xHash = hashFunction(pH->keyClass);
- assert( xHash!=0 );
- hraw = (*xHash)(pKey, nKey);
- assert( (pH->htsize & (pH->htsize-1))==0 );
- h = hraw & (pH->htsize-1);
- elem = findElementGivenHash(pH,pKey,nKey,h);
- if( elem ){
- void *old_data = elem->data;
- if( data==0 ){
- removeElementGivenHash(pH,elem,h);
- }else{
- elem->data = data;
- }
- return old_data;
- }
- if( data==0 ) return 0;
- new_elem = (HashElem*)Odie_Alloc( sizeof(HashElem) );
- if( new_elem==0 ) return data;
- if( pH->copyKey && pKey!=0 ){
- new_elem->pKey = Odie_Alloc( nKey );
- if( new_elem->pKey==0 ){
- Odie_Free((char *)new_elem);
- return data;
- }
- memcpy((void*)new_elem->pKey, pKey, nKey);
- }else{
- new_elem->pKey = (void*)pKey;
- }
- new_elem->nKey = nKey;
- pH->count++;
- if( pH->htsize==0 ) rehash(pH,8);
- if( pH->htsize==0 ){
- pH->count = 0;
- Odie_Free((char *)new_elem);
- return data;
- }
- if( pH->count > pH->htsize ){
- rehash(pH,pH->htsize*2);
- }
- assert( (pH->htsize & (pH->htsize-1))==0 );
- h = hraw & (pH->htsize-1);
- elem = pH->ht[h].chain;
- if( elem ){
- new_elem->next = elem;
- new_elem->prev = elem->prev;
- if( elem->prev ){ elem->prev->next = new_elem; }
- else { pH->first = new_elem; }
- elem->prev = new_elem;
- }else{
- new_elem->next = pH->first;
- new_elem->prev = 0;
- if( pH->first ){ pH->first->prev = new_elem; }
- pH->first = new_elem;
- }
- pH->ht[h].count++;
- pH->ht[h].chain = new_elem;
- new_elem->data = data;
- return 0;
- }
- /* int */
- void TreeInit(Tree *tree, int (*xCompare)(const void*, const void*),void *(*xCopy)(const void*),void (*xFree)(void*)){
- /* Turn bulk memory into a Tree structure
- Tree *tree, Tree object to initialize
- int (*xCompare)(const void*, const void*), Comparison function
- void *(*xCopy)(const void*), Key copy function or NULL
- void (*xFree)(void*) Key delete function or NULL
- */
- tree->xCompare = xCompare;
- tree->xCopy = xCopy;
- tree->xFree = xFree;
- tree->top = 0;
- }
- /* TreeCount */
- int TreeCount(Tree *pTree){
- /* Return the number of elements in the tree. */
- if( pTree && pTree->top ){
- return pTree->top->weight;
- }else{
- return 0;
- }
- }
- /* void */
- static void TreeClearNode(TreeElem *p, void (*xFree)(void*)){
- /* Delete a single node of the binary tree and all of its children */
- if( p==0 ) return;
- if( p->left ) TreeClearNode(p->left, xFree);
- if( p->right ) TreeClearNode(p->right, xFree);
- if( xFree ){
- xFree(p->key);
- }
- Tcl_Free((char *)p);
- }
- /* TreeClear */
- void TreeClear(Tree *tree){
- /* Remove all nodes from a tree */
- if( tree->top ){
- TreeClearNode(tree->top, tree->xFree);
- }
- tree->top = 0;
- }
- /* *TreeFind */
- void *TreeFind(Tree *tree, const void *key){
- /* Find the element of the tree (if any) whose key matches "key".
- ** Return a pointer to the data for that element. If no match
- ** is found, return NULL.
- */
- TreeElem *p;
- p = tree->top;
- while( p ){
- int c = tree->xCompare(p->key, key);
- if( c==0 ){
- return p->data;
- }else if( c<0 ){
- p = p->right;
- }else{
- p = p->left;
- }
- }
- return 0;
- }
- /* TreeRank */
- int TreeRank(Tree *tree, const void *key){
- /* If the node with key "key" is the left-most element of the tree,
- ** return 0. If it is the second to the left, return 1. And so
- ** forth.
- **
- ** If there is no node in the tree with the key "key", then return
- ** the number that would have been returned if such a node were
- ** inserted.
- */
- TreeElem *p;
- int rank = 0;
- p = tree->top;
- while( p ){
- int c = tree->xCompare(p->key, key);
- if( c==0 ){
- rank += p->left ? p->left->weight: 0;
- break;
- }else if( c<0 ){
- rank += (p->left ? p->left->weight: 0) + 1;
- p = p->right;
- }else{
- p = p->left;
- }
- }
- return rank;
- }
- /* *TreeFindNthElem */
- static TreeElem *TreeFindNthElem(Tree *tree, int n){
- /* Return a pointer to the N-th element of a tree. (The left-most
- ** element is number 0, the next is number 1 and so forth.)
- */
- TreeElem *p;
- p = tree->top;
- while( p ){
- int c = p->left ? p->left->weight : 0;
- if( n==c ){
- return p;
- }else if( n>c ){
- n -= c+1;
- p = p->right;
- }else{
- p = p->left;
- }
- }
- return 0;
- }
- /* *TreeData */
- void *TreeData(Tree *tree, int n){
- /* Return the data associated with the N-th element of the tree. Return
- ** NULL if there is no N-th element.
- */
- TreeElem *p = TreeFindNthElem(tree,n);
- return p ? p->data : 0;
- }
- /* *TreeKey */
- const void *TreeKey(Tree *tree, int n){
- /* Return the key associated with the N-th element of the tree. Return
- ** NULL if there is no N-th element.
- */
- TreeElem *p = TreeFindNthElem(tree,n);
- if( p ){
- return p->key;
- }else{
- return 0;
- }
- }
- /* TreeBalance */
- static void TreeBalance(TreeElem **ppElem){
- /*
- ** Definitions:
- ** WEIGHT
- ** The weight of a node is the total number of children for the node
- ** plus 1. Leaf nodes have a weight of 1. The root node has a weight
- ** which equals the number of nodes in the tree.
- **
- ** BALANCE
- ** A node is balanced if the weight of the one child is not more than
- ** twice the weight of the other child.
- */
- /* The following routine rebalances the tree rooted at *ppElem after
- ** the insertion or deletion of a single ancestor.
- */
- TreeElem *n; /* Pointer to self */
- int l,r; /* Weight of left and right daughters */
- int a,b; /* Weights of various nodes */
- if( ppElem==0 || (n=*ppElem)==0 ) return;
- l = n->left ? n->left->weight: 0;
- r = n->right ? n->right->weight: 0;
- if( l>r*2 ){ /* Too heavy on the left side */
- TreeElem *nl; /* Pointer to left daughter */
- TreeElem *nr; /* Pointer to right daughter */
- int ll, lr; /* Weight of left daughter's left and right daughter */
- nl = n->left;
- ll = nl->left ? nl->left->weight: 0;
- lr = nl->right ? nl->right->weight: 0;
- if( ll>lr || nl->right==0 ){
- /*
- ** Convert from: n to: nl
- ** / \ / ** nl c a n
- ** / \ / ** a b b c
- */
- n->left = nl->right;
- nl->right = n;
- n->weight = a = r + lr + 1;
- nl->weight = a + ll + 1;
- *ppElem = nl;
- }else{
- /*
- ** Convert from: n to: nr
- ** / \ / ** nl d nl n
- ** / \ / \ / ** a nr a b c d
- ** / ** b c
- */
- int lrl, lrr; /* Weight of Great-granddaughter nodes */
- nr = nl->right;
- lrl = nr->left ? nr->left->weight: 0;
- lrr = nr->right ? nr->right->weight: 0;
- nl->right = nr->left;
- nr->left = nl;
- n->left = nr->right;
- nr->right = n;
- n->weight = a = lrr + r + 1;
- nl->weight = b = ll + lrl + 1;
- nr->weight = a + b + 1;
- *ppElem = nr;
- }
- }else if( r>l*2 ){/* Too deep on the right side */
- TreeElem *nl; /* Pointer to left daughter */
- TreeElem *nr; /* Pointer to right daughter */
- int rl, rr; /* Weight of right daughter's left and right daughter */
- nr = n->right;
- rl = nr->left ? nr->left->weight: 0;
- rr = nr->right ? nr->right->weight: 0;
- if( rr>rl || nr->left==0 ){
- /*
- ** Convert from: n to: nr
- ** / \ / ** a nr n c
- ** / \ / ** b c a b
- */
- n->right = nr->left;
- nr->left = n;
- n->weight = a = l + rl + 1;
- nr->weight = a + rr + 1;
- *ppElem = nr;
- }else{
- /*
- ** Convert from: n to: nl
- ** / \ / ** a nr n nr
- ** / \ / \ / ** nl d a b c d
- ** / ** b c
- */
- int rll,rlr; /* Weights of great-granddaughter nodes */
- nl = nr->left;
- rll = nl->left ? nl->left->weight: 0;
- rlr = nl->right ? nl->right->weight: 0;
- nr->left = nl->right;
- nl->right = nr;
- n->right = nl->left;
- nl->left = n;
- n->weight = a = l + rll + 1;
- nr->weight = b = rr + rlr + 1;
- nl->weight = a + b + 1;
- *ppElem = nl;
- }
- }else{ /* Node is already balanced. Just recompute its weight. */
- n->weight = l + r + 1;
- }
- }
- /* *TreeInsertElement */
- static void *TreeInsertElement(Tree *pTree, void *key, void *data){
- /*
- Tree *pTree, The root of the tree
- void *key, Insert data at this key
- void *data Data to be inserted
- */
- /* This routine either changes the data on an existing node in the tree,
- ** or inserts a new node. "key" identifies the node. If the data on
- ** an existing node is changed, then the function returns the old data.
- ** If a new node is created, NULL is returned.
- */
- TreeElem *n;
- void *old = 0;
- TreeElem **h[100]; /* Sufficient for a tree with up to 4.0E+17 nodes */
- int level = 0;
- h[0] = &pTree->top;
- level = 1;
- n = pTree->top;
- while( n ){
- int c;
- c = pTree->xCompare(key, n->key);
- if( c<0 ){
- h[level++] = &(n->left);
- n = n->left;
- }else if( c>0 ){
- h[level++] = &(n->right);
- n = n->right;
- }else{
- old = n->data;
- n->data = data; /* Replace data in an existing node */
- break;
- }
- }
- if( n==0 ){ /* Insert a leaf node */
- level--;
- n = *h[level] = (TreeElem *)Tcl_Alloc( sizeof(TreeElem) );
- if( n==0 ){
- return data;
- }
- n->data = data;
- if( pTree->xCopy ){
- n->key = pTree->xCopy(key);
- }else{
- n->key = key;
- }
- n->left = n->right = 0;
- while( level>=0 ) TreeBalance(h[level--]);
- }
- return old;
- }
- /* *TreeDeleteNthElem */
- static TreeElem *TreeDeleteNthElem(TreeElem **ppTop, int N){
- /* Unlink the N-th node of the tree and return a pointer to that
- ** node. (The left-most node is 0, the next node to the right is
- ** 1 and so forth.)
- */
- TreeElem *p; /* For walking the tree */
- int level = 0; /* Depth of the blancing stack */
- TreeElem **h[100]; /* Balance stack. 100 is sufficient for balancing
- ** a tree with up to 4.0E+17 nodes */
- h[0] = ppTop;
- level = 1;
- p = *ppTop;
- while( p ){
- int w;
- w = (p->left ? p->left->weight: 0);
- if( N>w ){
- h[level++] = &(p->right);
- p = p->right;
- N -= w+1;
- }else if( N<w ){
- h[level++] = &(p->left);
- p = p->left;
- }else{
- break;
- }
- }
- if( p ){
- level--;
- if( p->left==0 ){
- *h[level] = p->right;
- level--;
- }else if( p->right==0 ){
- *h[level] = p->left;
- level--;
- }else{
- TreeElem *x;
- x = TreeDeleteNthElem(&(p->right),0);
- x->right = p->right;
- x->left = p->left;
- *h[level] = x;
- }
- while( level>=0 ) TreeBalance(h[level--]);
- }
- return p;
- }
- /* *TreeDeleteElem */
- static TreeElem *TreeDeleteElem(Tree *tree, const void *key){
- /* Unlink the node of the tree corresponding to key and return a pointer
- ** to that node.
- */
- TreeElem *p; /* For walking the tree */
- int level = 0; /* Depth of the blancing stack */
- TreeElem **h[100]; /* Balance stack. 100 is sufficient for balancing
- ** a tree with up to 4.0E+17 nodes */
- h[0] = &tree->top;
- level = 1;
- p = tree->top;
- while( p ){
- int w;
- w = tree->xCompare(p->key, key);
- if( w<0 ){
- h[level++] = &(p->right);
- p = p->right;
- }else if( w>0 ){
- h[level++] = &(p->left);
- p = p->left;
- }else{
- break;
- }
- }
- if( p ){
- level--;
- if( p->left==0 ){
- *h[level] = p->right;
- level--;
- }else if( p->right==0 ){
- *h[level] = p->left;
- level--;
- }else{
- TreeElem *x;
- x = TreeDeleteNthElem(&(p->right),0);
- x->right = p->right;
- x->left = p->left;
- *h[level] = x;
- }
- while( level>=0 ) TreeBalance(h[level--]);
- }
- return p;
- }
- /* *TreeInsert */
- void *TreeInsert(Tree *tree, void *key, void *data){
- /* Insert new data into a node of the tree. The node is identified
- ** by "key".
- **
- ** If the new data is NULL, then node is deleted.
- **
- ** If the node aready exists, the new data overwrites the old and
- ** the old data is returned. If the node doesn't already exist, then
- ** a new node is created and the function returns NULL.
- */
- void *old;
- if( data==0 ){
- TreeElem *elem = TreeDeleteElem(tree, key);
- if( elem ){
- if( tree->xFree ){
- tree->xFree(elem->key);
- }
- old = elem->data;
- Tcl_Free((char *)elem);
- }else{
- old = 0;
- }
- }else{
- old = TreeInsertElement(tree,key,data);
- }
- return old;
- }
- /* *TreeChangeNth */
- void *TreeChangeNth(Tree *tree, int n, void *data){
- /* Change the data on the n-th node of the tree. The old data
- ** is returned.
- **
- ** If data==NULL, then the n-th node of the tree is deleted. (The
- ** data associated with that node is still returned.)
- **
- ** If the value N is out-of-bounds, then no new node is created.
- ** Instead, the "data" parameter is returned.
- */
- void *old;
- if( data==0 ){
- TreeElem *elem = TreeDeleteNthElem(&tree->top,n);
- if( elem ){
- if( tree->xFree ){
- tree->xFree(elem->key);
- }
- old = elem->data;
- Tcl_Free((char *)elem);
- }else{
- old = 0;
- }
- }else{
- TreeElem *elem = TreeFindNthElem(tree,n);
- if( elem ){
- old = elem->data;
- elem->data = data;
- }else{
- old = data;
- }
- }
- return old;
- }
- /* Odie_GetMatrixElementFromObj */
- static inline int Odie_GetMatrixElementFromObj(Tcl_Interp *interp,Tcl_Obj *objPtr,double *R,int idx){
- double temp;
- if( Tcl_GetDoubleFromObj(interp, objPtr, &temp) ) return TCL_ERROR;
- R[idx]=temp;
- return TCL_OK;
- }
- /* hashInt */
- static inline unsigned int hashInt(int x){
- /*
- ** Compute a hash on an integer.
- */
- return (x & 0x7fffffff) % SZ_HASH;
- }
- /* intCoord */
- static inline long intCoord(double x){
- /*
- ** Round a coordinate to its nearest grain boundary
- */
- long idxX = x/OdieGrain + (x>0.0 ? 0.5 : -0.5);
- return idxX*OdieGrain;
- }
- /* hashPoint */
- static inline unsigned int hashPoint(VECTORXY p){
- /*
- ** Compute a hash on a point.
- */
- long x=intCoord(p[X_IDX])*ODIE_X_HASH;
- long y=intCoord(p[Y_IDX])*ODIE_Y_HASH;
- return hashInt(x ^ y);
- }
- /* hashVectorXY */
- static inline unsigned int hashVectorXY(VECTORXY p){
- long x=intCoord(p[X_IDX])*ODIE_X_HASH;
- long y=intCoord(p[Y_IDX])*ODIE_Y_HASH;
- return hashInt(x ^ y);
- }
- /* hashVectorXYZ */
- static inline unsigned int hashVectorXYZ(VECTORXYZ p){
- long x=intCoord(p[X_IDX])*ODIE_X_HASH;
- long y=intCoord(p[Y_IDX])*ODIE_Y_HASH;
- long z=intCoord(p[Z_IDX])*ODIE_Z_HASH;
- if(z!=0) {
- return hashInt(x ^ y ^ z);
- } else {
- return hashInt(x ^ y);
- }
- }
- /* roundCoord */
- static inline double roundCoord(double x){
- return intCoord(x);
- }
- /* hashCoord */
- static inline int hashCoord(double x, double y){
- /*
- ** Compute a hash on a pair of floating point number.
- */
- long idxX = intCoord(x)*ODIE_X_HASH;
- long idxY = intCoord(y)*ODIE_Y_HASH;
- return hashInt(idxX ^ idxY);
- }
- /* hashCoord3d */
- static inline int hashCoord3d(double x, double y,double z){
- /*
- ** Compute a hash on a pair of floating point number.
- */
- long idxX = intCoord(x)*ODIE_X_HASH;
- long idxY = intCoord(y)*ODIE_Y_HASH;
- long idxZ = intCoord(z)*ODIE_Z_HASH;
- if(idxZ!=0) {
- return hashInt(idxX ^ idxY ^ idxZ);
- } else {
- return hashInt(idxX ^ idxY);
- }
- }
- /* floatCompare */
- static inline int floatCompare(double x0, double x1){
- /*
- ** Compare to floating point values and return negative, zero, or
- ** positive if the first value is less than, equal to, or greater
- ** than the second.
- */
- double diff = x1 - x0;
- if( diff>-OdieGrain && diff<OdieGrain ){
- diff = 0.0;
- }
- return (int)diff;
- }
- /* GridCoord */
- static inline void GridCoord(double *x, double *y){
- /*
- ** Round a set of coordinates by OdieGrain
- */
- *x=round(*x/OdieGrain)*OdieGrain;
- *y=round(*y/OdieGrain)*OdieGrain;
- }
- /* Math_Const_Init */
- int Math_Const_Init(Tcl_Interp *interp){
- Tcl_Obj *varname=Tcl_NewStringObj("math_const",-1);
- Tcl_IncrRefCount(varname);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_2_x_pi",-1),Tcl_NewDoubleObj(M_2_X_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_pi_180",-1),Tcl_NewDoubleObj(M_PI_180),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_pi_360",-1),Tcl_NewDoubleObj(M_PI_360),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_e",-1),Tcl_NewDoubleObj(M_E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_log2e",-1),Tcl_NewDoubleObj(M_LOG2E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_log10e",-1),Tcl_NewDoubleObj(M_LOG10E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_ln2",-1),Tcl_NewDoubleObj(M_LN2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_ln10",-1),Tcl_NewDoubleObj(M_LN10),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_pi",-1),Tcl_NewDoubleObj(M_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_pi_2",-1),Tcl_NewDoubleObj(M_PI_2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_pi_4",-1),Tcl_NewDoubleObj(M_PI_4),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_1_pi",-1),Tcl_NewDoubleObj(M_1_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_2_pi",-1),Tcl_NewDoubleObj(M_2_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_2_sqrtpi",-1),Tcl_NewDoubleObj(M_2_SQRTPI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_sqrt2",-1),Tcl_NewDoubleObj(M_SQRT2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_sqrt1_2",-1),Tcl_NewDoubleObj(M_SQRT1_2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_sqrt3",-1),Tcl_NewDoubleObj(M_SQRT3),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,varname,Tcl_NewStringObj("m_sqrt3_2",-1),Tcl_NewDoubleObj(M_SQRT3_2),TCL_GLOBAL_ONLY);
- Tcl_DecrRefCount(varname);
- return TCL_OK;}
- /* VectorXYZ_AABB_Normalize */
- static inline void VectorXYZ_AABB_Normalize(AABBXYZ R){
- double temp;
- if (R[X_MIN_IDX] > R[X_MAX_IDX]) {
- temp=R[X_MIN_IDX];
- R[X_MIN_IDX]=R[X_MAX_IDX];
- R[X_MAX_IDX]=temp;
- } if (R[Y_MIN_IDX] > R[Y_MAX_IDX]) {
- temp=R[Y_MIN_IDX];
- R[Y_MIN_IDX]=R[Y_MAX_IDX];
- R[Y_MAX_IDX]=temp;
- } if (R[Z_MIN_IDX] > R[Z_MAX_IDX]) {
- temp=R[Z_MIN_IDX];
- R[Z_MIN_IDX]=R[Z_MAX_IDX];
- R[Z_MAX_IDX]=temp;
- }}
- /* VectorXYZ_AABB_Copy */
- static void VectorXYZ_AABB_Copy(AABBXYZ dest,AABBXYZ src){
- dest[X_MIN_IDX]=src[X_MIN_IDX];
- dest[X_MAX_IDX]=src[X_MAX_IDX];
- dest[Y_MIN_IDX]=src[Y_MIN_IDX];
- dest[Y_MAX_IDX]=src[Y_MAX_IDX];
- dest[Z_MIN_IDX]=src[Z_MIN_IDX];
- dest[Z_MAX_IDX]=src[Z_MAX_IDX];
- }
- /* VectorXYZ_AABB_Within */
- static inline int VectorXYZ_AABB_Within(VectorXYZ POINT,AABBXYZ R){
- if (POINT[X_IDX]<R[X_MIN_IDX]) return 0;
- if (POINT[X_IDX]>R[X_MAX_IDX]) return 0;
- if (POINT[Y_IDX]<R[Y_MIN_IDX]) return 0;
- if (POINT[Y_IDX]>R[Y_MAX_IDX]) return 0;
- if (POINT[Z_IDX]<R[Z_MIN_IDX]) return 0;
- if (POINT[Z_IDX]>R[Z_MAX_IDX]) return 0;
- return 1;
- }
- /* VectorXYZ_BBOX_Overlap_TwoVectors */
- static inline int VectorXYZ_BBOX_Overlap_TwoVectors(VectorXYZ A1,VectorXYZ A2,VectorXYZ B1,VectorXYZ B2){
- if (A1[X_IDX]<B1[X_IDX] && A1[X_IDX]<B2[X_IDX]) {
- if (A2[X_IDX]<B1[X_IDX] && A2[X_IDX]<B2[X_IDX]) return 0;
- }
- if (A1[X_IDX]>B1[X_IDX] && A1[X_IDX]>B2[X_IDX]) {
- if (A2[X_IDX]>B1[X_IDX] && A2[X_IDX]>B2[X_IDX]) return 0;
- }
- if (A1[Y_IDX]<B1[Y_IDX] && A1[Y_IDX]<B2[Y_IDX]) {
- if (A2[Y_IDX]<B1[Y_IDX] && A2[Y_IDX]<B2[Y_IDX]) return 0;
- }
- if (A1[Y_IDX]>B1[Y_IDX] && A1[Y_IDX]>B2[Y_IDX]) {
- if (A2[Y_IDX]>B1[Y_IDX] && A2[Y_IDX]>B2[Y_IDX]) return 0;
- }
- if (A1[Z_IDX]<B1[Z_IDX] && A1[Z_IDX]<B2[Z_IDX]) {
- if (A2[Z_IDX]<B1[Z_IDX] && A2[Z_IDX]<B2[Z_IDX]) return 0;
- }
- if (A1[Z_IDX]>B1[Z_IDX] && A1[Z_IDX]>B2[Z_IDX]) {
- if (A2[Z_IDX]>B1[Z_IDX] && A2[Z_IDX]>B2[Z_IDX]) return 0;
- }
- return 1;
- }
- /* AABB_AABB_Intersect */
- static inline int AABB_AABB_Intersect(AABBXYZ A,AABBXYZ B){
- int a_inside_b=0;
- int b_inside_a=0;
- if (A[X_MIN_IDX]>=B[X_MIN_IDX] && A[X_MAX_IDX]<=B[X_MAX_IDX]) a_inside_b++;
- if (B[X_MIN_IDX]>=A[X_MIN_IDX] && B[X_MAX_IDX]<=A[X_MAX_IDX]) b_inside_a++;
- if (A[Y_MIN_IDX]>=B[Y_MIN_IDX] && A[Y_MAX_IDX]<=B[Y_MAX_IDX]) a_inside_b++;
- if (B[Y_MIN_IDX]>=A[Y_MIN_IDX] && B[Y_MAX_IDX]<=A[Y_MAX_IDX]) b_inside_a++;
- if (A[Z_MIN_IDX]>=B[Z_MIN_IDX] && A[Z_MAX_IDX]<=B[Z_MAX_IDX]) a_inside_b++;
- if (B[Z_MIN_IDX]>=A[Z_MIN_IDX] && B[Z_MAX_IDX]<=A[Z_MAX_IDX]) b_inside_a++;
- if (a_inside_b==0 && b_inside_a==0) return 0;
- if (a_inside_b==3 && b_inside_a==3) return 2;
- if (a_inside_b==3) return 3;
- if (b_inside_a==3) return 4;
- return 1;
- }
- /* VectorXYZ_AABB_Measure */
- static inline void VectorXYZ_AABB_Measure(VectorXYZ POINT,AABBXYZ R){
- if (POINT[X_IDX]<R[X_MIN_IDX]) R[X_MIN_IDX]=POINT[X_IDX];
- if (POINT[X_IDX]>R[X_MAX_IDX]) R[X_MAX_IDX]=POINT[X_IDX];
- if (POINT[Y_IDX]<R[Y_MIN_IDX]) R[Y_MIN_IDX]=POINT[Y_IDX];
- if (POINT[Y_IDX]>R[Y_MAX_IDX]) R[Y_MAX_IDX]=POINT[Y_IDX];
- if (POINT[Z_IDX]<R[Z_MIN_IDX]) R[Z_MIN_IDX]=POINT[Z_IDX];
- if (POINT[Z_IDX]>R[Z_MAX_IDX]) R[Z_MAX_IDX]=POINT[Z_IDX];
- }
- /* AABB_AABB_Combine */
- static inline void AABB_AABB_Combine(AABBXYZ B,AABBXYZ A){
- if (A[X_MIN_IDX]<B[X_MIN_IDX]) B[X_MIN_IDX]=A[X_MIN_IDX];
- if (A[X_MAX_IDX]>B[X_MAX_IDX]) B[X_MAX_IDX]=A[X_MAX_IDX];
- if (A[Y_MIN_IDX]<B[Y_MIN_IDX]) B[Y_MIN_IDX]=A[Y_MIN_IDX];
- if (A[Y_MAX_IDX]>B[Y_MAX_IDX]) B[Y_MAX_IDX]=A[Y_MAX_IDX];
- if (A[Z_MIN_IDX]<B[Z_MIN_IDX]) B[Z_MIN_IDX]=A[Z_MIN_IDX];
- if (A[Z_MAX_IDX]>B[Z_MAX_IDX]) B[Z_MAX_IDX]=A[Z_MAX_IDX];
- }
- /* VectorXYZ_AABB_Reset */
- static inline void VectorXYZ_AABB_Reset(AABBXYZ R){
- R[X_MIN_IDX]=R[Y_MIN_IDX]=R[Z_MIN_IDX]=1e99;
- R[X_MAX_IDX]=R[Y_MAX_IDX]=R[Z_MAX_IDX]=-1e99;
- }
- VectorXYZ Odie_Up_Direction = {0, 0, 1.0};
- /* *Matrix_To_affine */
- const char *Matrix_To_affine(Odie_MatrixObj *matrix,int form){
- if(matrix->form==MATFORM_affine) {
- return NULL;
- }
- if(matrix->form==MATFORM_euler) {
- VectorXYZ TEMP;
- VectorXYZ_Copy(TEMP,matrix->matrix);
- affine_Rotate_From_Euler(TEMP,matrix->matrix);
- matrix->form=MATFORM_affine;
- return NULL;
- }
- if(matrix->form==MATFORM_vector_xyz) {
- VectorXYZ TEMP;
- VectorXYZ_Copy(TEMP,matrix->matrix);
- Odie_Affine4x4_Translation(TEMP,matrix->matrix);
- matrix->form=MATFORM_affine;
- return NULL;
- }
- if(matrix->rows==4 && matrix->cols==4) {
- if(matrix->form==MATFORM_null) {
- matrix->form=MATFORM_affine;
- }
- return NULL;
- }
- if(matrix->rows==1 && matrix->cols==16) {
- if(matrix->form==MATFORM_null) {
- matrix->form=MATFORM_affine;
- }
- return NULL;
- }
- if(matrix->rows==16 && matrix->cols==1) {
- if(matrix->form==MATFORM_null) {
- matrix->form=MATFORM_affine;
- }
- return NULL;
- }
- return "Cannot convert to affine";
- }
- /* affine_Compare */
- static inline int affine_Compare(AFFINE A,AFFINE B){
- if(fabs(B[AFFINE_IDX_0_0]-A[AFFINE_IDX_0_0])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_0_1]-A[AFFINE_IDX_0_1])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_0_2]-A[AFFINE_IDX_0_2])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_0_3]-A[AFFINE_IDX_0_3])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_1_0]-A[AFFINE_IDX_1_0])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_1_1]-A[AFFINE_IDX_1_1])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_1_2]-A[AFFINE_IDX_1_2])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_1_3]-A[AFFINE_IDX_1_3])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_2_0]-A[AFFINE_IDX_2_0])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_2_1]-A[AFFINE_IDX_2_1])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_2_2]-A[AFFINE_IDX_2_2])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_2_3]-A[AFFINE_IDX_2_3])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_3_0]-A[AFFINE_IDX_3_0])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_3_1]-A[AFFINE_IDX_3_1])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_3_2]-A[AFFINE_IDX_3_2])>__FLT_EPSILON__) return 0;
- if(fabs(B[AFFINE_IDX_3_3]-A[AFFINE_IDX_3_3])>__FLT_EPSILON__) return 0;
- return 1;
- }
- /* Odie_Affine4x4_Copy */
- inline extern void Odie_Affine4x4_Copy(AFFINE RESULT,AFFINE A){
- RESULT[AFFINE_IDX_0_0]=A[AFFINE_IDX_0_0];
- RESULT[AFFINE_IDX_0_1]=A[AFFINE_IDX_0_1];
- RESULT[AFFINE_IDX_0_2]=A[AFFINE_IDX_0_2];
- RESULT[AFFINE_IDX_0_3]=A[AFFINE_IDX_0_3];
- RESULT[AFFINE_IDX_1_0]=A[AFFINE_IDX_1_0];
- RESULT[AFFINE_IDX_1_1]=A[AFFINE_IDX_1_1];
- RESULT[AFFINE_IDX_1_2]=A[AFFINE_IDX_1_2];
- RESULT[AFFINE_IDX_1_3]=A[AFFINE_IDX_1_3];
- RESULT[AFFINE_IDX_2_0]=A[AFFINE_IDX_2_0];
- RESULT[AFFINE_IDX_2_1]=A[AFFINE_IDX_2_1];
- RESULT[AFFINE_IDX_2_2]=A[AFFINE_IDX_2_2];
- RESULT[AFFINE_IDX_2_3]=A[AFFINE_IDX_2_3];
- RESULT[AFFINE_IDX_3_0]=A[AFFINE_IDX_3_0];
- RESULT[AFFINE_IDX_3_1]=A[AFFINE_IDX_3_1];
- RESULT[AFFINE_IDX_3_2]=A[AFFINE_IDX_3_2];
- RESULT[AFFINE_IDX_3_3]=A[AFFINE_IDX_3_3];
- }
- /* affine_ZeroMatrix */
- inline extern void affine_ZeroMatrix(AFFINE A){
- A[AFFINE_IDX_0_0]=0.0;
- A[AFFINE_IDX_0_1]=0.0;
- A[AFFINE_IDX_0_2]=0.0;
- A[AFFINE_IDX_0_3]=0.0;
- A[AFFINE_IDX_1_0]=0.0;
- A[AFFINE_IDX_1_1]=0.0;
- A[AFFINE_IDX_1_2]=0.0;
- A[AFFINE_IDX_1_3]=0.0;
- A[AFFINE_IDX_2_0]=0.0;
- A[AFFINE_IDX_2_1]=0.0;
- A[AFFINE_IDX_2_2]=0.0;
- A[AFFINE_IDX_2_3]=0.0;
- A[AFFINE_IDX_3_0]=0.0;
- A[AFFINE_IDX_3_1]=0.0;
- A[AFFINE_IDX_3_2]=0.0;
- A[AFFINE_IDX_3_3]=0.0;
- }
- /* Odie_Affine4x4_Identity */
- inline extern void Odie_Affine4x4_Identity(AFFINE A){
- A[AFFINE_IDX_0_0]=1.0;
- A[AFFINE_IDX_0_1]=0.0;
- A[AFFINE_IDX_0_2]=0.0;
- A[AFFINE_IDX_0_3]=0.0;
- A[AFFINE_IDX_1_0]=0.0;
- A[AFFINE_IDX_1_1]=1.0;
- A[AFFINE_IDX_1_2]=0.0;
- A[AFFINE_IDX_1_3]=0.0;
- A[AFFINE_IDX_2_0]=0.0;
- A[AFFINE_IDX_2_1]=0.0;
- A[AFFINE_IDX_2_2]=1.0;
- A[AFFINE_IDX_2_3]=0.0;
- A[AFFINE_IDX_3_0]=0.0;
- A[AFFINE_IDX_3_1]=0.0;
- A[AFFINE_IDX_3_2]=0.0;
- A[AFFINE_IDX_3_3]=1.0;
- }
- /* Odie_Affine4x4_Translation */
- void Odie_Affine4x4_Translation(AFFINE RESULT,VECTOR A){
- Odie_Affine4x4_Identity(RESULT);
- RESULT[AFFINE_IDX_0_3]=-A[X_IDX];
- RESULT[AFFINE_IDX_1_3]=-A[Y_IDX];
- RESULT[AFFINE_IDX_2_3]=-A[Z_IDX];
- }
- /* Odie_Affine4x4_Scale */
- inline extern void Odie_Affine4x4_Scale(AFFINE RESULT,VECTOR A){
- Odie_Affine4x4_Identity(RESULT);
- RESULT[AFFINE_IDX_0_0]=A[X_IDX];
- RESULT[AFFINE_IDX_1_1]=A[Y_IDX];
- RESULT[AFFINE_IDX_2_2]=A[Z_IDX];
- RESULT[AFFINE_IDX_3_3]=1.0;
- }
- /* affine_rotate_nutation */
- inline extern void affine_rotate_nutation(AFFINE RESULT,SCALER theta){
- double cos_theta,sin_theta;
- cos_theta=cos(theta);
- sin_theta=sin(theta);
- Odie_Affine4x4_Identity(RESULT);
- RESULT[AFFINE_IDX_1_1]=cos_theta;
- RESULT[AFFINE_IDX_1_2]=sin_theta;
- RESULT[AFFINE_IDX_2_1]=-sin_theta;
- RESULT[AFFINE_IDX_2_2]=cos_theta;
- }
- /* affine_rotate_precession */
- inline extern void affine_rotate_precession(AFFINE RESULT,SCALER phi){
- double cos_phi,sin_phi;
- cos_phi=cos(phi);
- sin_phi=sin(phi);
- Odie_Affine4x4_Identity(RESULT);
- RESULT[AFFINE_IDX_0_0]=cos_phi;
- RESULT[AFFINE_IDX_0_1]=sin_phi;
- RESULT[AFFINE_IDX_1_0]=-sin_phi;
- RESULT[AFFINE_IDX_1_1]=cos_phi;
- }
- /* affine_rotate_spin */
- static inline void affine_rotate_spin(AFFINE RESULT,SCALER psi){
- double cos_psi,sin_psi;
- cos_psi=cos(psi);
- sin_psi=sin(psi);
- Odie_Affine4x4_Identity(RESULT);
- RESULT[AFFINE_IDX_0_0]=cos_psi;
- RESULT[AFFINE_IDX_0_1]=sin_psi;
- RESULT[AFFINE_IDX_1_0]=-sin_psi;
- RESULT[AFFINE_IDX_1_1]=cos_psi;
- }
- /* affine_Rotate_From_Euler */
- void affine_Rotate_From_Euler(AFFINE RESULT,VECTOR rotate){
- double cos_theta,sin_theta;
- double cos_phi,sin_phi;
- double cos_psi,sin_psi;
- cos_theta=cos(rotate[EULER_THETA]);
- sin_theta=sin(rotate[EULER_THETA]);
- cos_phi=cos(rotate[EULER_PHI]);
- sin_phi=sin(rotate[EULER_PHI]);
- cos_psi=cos(rotate[EULER_PSI]);
- sin_psi=sin(rotate[EULER_PSI]);
- RESULT[AFFINE_IDX_0_0]=cos_psi*cos_phi-cos_theta*sin_psi*sin_psi;
- RESULT[AFFINE_IDX_0_1]=cos_psi*sin_phi+cos_theta*cos_phi*sin_psi;
- RESULT[AFFINE_IDX_0_2]=sin_theta*sin_psi;
- RESULT[AFFINE_IDX_0_3]=0.0;
- RESULT[AFFINE_IDX_1_0]=-sin_psi*cos_phi-cos_theta*sin_phi*cos_psi;
- RESULT[AFFINE_IDX_1_1]=-sin_psi*sin_phi+cos_theta*cos_phi*cos_psi;
- RESULT[AFFINE_IDX_1_2]=sin_theta*cos_psi;
- RESULT[AFFINE_IDX_1_3]=0.0;
- RESULT[AFFINE_IDX_2_0]=sin_phi*sin_theta;
- RESULT[AFFINE_IDX_2_1]=-cos_phi*sin_theta;
- RESULT[AFFINE_IDX_2_2]=cos_theta;
- RESULT[AFFINE_IDX_2_3]=0.0;
- RESULT[AFFINE_IDX_3_0]=0.0;
- RESULT[AFFINE_IDX_3_1]=0.0;
- RESULT[AFFINE_IDX_3_2]=0.0;
- RESULT[AFFINE_IDX_3_3]=1.0;
- }
- /* Odie_Affine4x4_Multiply */
- inline extern void Odie_Affine4x4_Multiply(AFFINE R,AFFINE A,AFFINE B){
- double cell_0_0;
- double cell_0_1;
- double cell_0_2;
- double cell_0_3;
- double cell_1_0;
- double cell_1_1;
- double cell_1_2;
- double cell_1_3;
- double cell_2_0;
- double cell_2_1;
- double cell_2_2;
- double cell_2_3;
- double cell_3_0;
- double cell_3_1;
- double cell_3_2;
- double cell_3_3;
- cell_0_0=A[AFFINE_IDX_0_0]*B[AFFINE_IDX_0_0]+A[AFFINE_IDX_0_1]*B[AFFINE_IDX_1_0]+A[AFFINE_IDX_0_2]*B[AFFINE_IDX_2_0]+A[AFFINE_IDX_0_3]*B[AFFINE_IDX_3_0];
- cell_0_1=A[AFFINE_IDX_0_0]*B[AFFINE_IDX_0_1]+A[AFFINE_IDX_0_1]*B[AFFINE_IDX_1_1]+A[AFFINE_IDX_0_2]*B[AFFINE_IDX_2_1]+A[AFFINE_IDX_0_3]*B[AFFINE_IDX_3_1];
- cell_0_2=A[AFFINE_IDX_0_0]*B[AFFINE_IDX_0_2]+A[AFFINE_IDX_0_1]*B[AFFINE_IDX_1_2]+A[AFFINE_IDX_0_2]*B[AFFINE_IDX_2_2]+A[AFFINE_IDX_0_3]*B[AFFINE_IDX_3_2];
- cell_0_3=A[AFFINE_IDX_0_0]*B[AFFINE_IDX_0_3]+A[AFFINE_IDX_0_1]*B[AFFINE_IDX_1_3]+A[AFFINE_IDX_0_2]*B[AFFINE_IDX_2_3]+A[AFFINE_IDX_0_3]*B[AFFINE_IDX_3_3];
- cell_1_0=A[AFFINE_IDX_1_0]*B[AFFINE_IDX_0_0]+A[AFFINE_IDX_1_1]*B[AFFINE_IDX_1_0]+A[AFFINE_IDX_1_2]*B[AFFINE_IDX_2_0]+A[AFFINE_IDX_1_3]*B[AFFINE_IDX_3_0];
- cell_1_1=A[AFFINE_IDX_1_0]*B[AFFINE_IDX_0_1]+A[AFFINE_IDX_1_1]*B[AFFINE_IDX_1_1]+A[AFFINE_IDX_1_2]*B[AFFINE_IDX_2_1]+A[AFFINE_IDX_1_3]*B[AFFINE_IDX_3_1];
- cell_1_2=A[AFFINE_IDX_1_0]*B[AFFINE_IDX_0_2]+A[AFFINE_IDX_1_1]*B[AFFINE_IDX_1_2]+A[AFFINE_IDX_1_2]*B[AFFINE_IDX_2_2]+A[AFFINE_IDX_1_3]*B[AFFINE_IDX_3_2];
- cell_1_3=A[AFFINE_IDX_1_0]*B[AFFINE_IDX_0_3]+A[AFFINE_IDX_1_1]*B[AFFINE_IDX_1_3]+A[AFFINE_IDX_1_2]*B[AFFINE_IDX_2_3]+A[AFFINE_IDX_1_3]*B[AFFINE_IDX_3_3];
- cell_2_0=A[AFFINE_IDX_2_0]*B[AFFINE_IDX_0_0]+A[AFFINE_IDX_2_1]*B[AFFINE_IDX_1_0]+A[AFFINE_IDX_2_2]*B[AFFINE_IDX_2_0]+A[AFFINE_IDX_2_3]*B[AFFINE_IDX_3_0];
- cell_2_1=A[AFFINE_IDX_2_0]*B[AFFINE_IDX_0_1]+A[AFFINE_IDX_2_1]*B[AFFINE_IDX_1_1]+A[AFFINE_IDX_2_2]*B[AFFINE_IDX_2_1]+A[AFFINE_IDX_2_3]*B[AFFINE_IDX_3_1];
- cell_2_2=A[AFFINE_IDX_2_0]*B[AFFINE_IDX_0_2]+A[AFFINE_IDX_2_1]*B[AFFINE_IDX_1_2]+A[AFFINE_IDX_2_2]*B[AFFINE_IDX_2_2]+A[AFFINE_IDX_2_3]*B[AFFINE_IDX_3_2];
- cell_2_3=A[AFFINE_IDX_2_0]*B[AFFINE_IDX_0_3]+A[AFFINE_IDX_2_1]*B[AFFINE_IDX_1_3]+A[AFFINE_IDX_2_2]*B[AFFINE_IDX_2_3]+A[AFFINE_IDX_2_3]*B[AFFINE_IDX_3_3];
- cell_3_0=A[AFFINE_IDX_3_0]*B[AFFINE_IDX_0_0]+A[AFFINE_IDX_3_1]*B[AFFINE_IDX_1_0]+A[AFFINE_IDX_3_2]*B[AFFINE_IDX_2_0]+A[AFFINE_IDX_3_3]*B[AFFINE_IDX_3_0];
- cell_3_1=A[AFFINE_IDX_3_0]*B[AFFINE_IDX_0_1]+A[AFFINE_IDX_3_1]*B[AFFINE_IDX_1_1]+A[AFFINE_IDX_3_2]*B[AFFINE_IDX_2_1]+A[AFFINE_IDX_3_3]*B[AFFINE_IDX_3_1];
- cell_3_2=A[AFFINE_IDX_3_0]*B[AFFINE_IDX_0_2]+A[AFFINE_IDX_3_1]*B[AFFINE_IDX_1_2]+A[AFFINE_IDX_3_2]*B[AFFINE_IDX_2_2]+A[AFFINE_IDX_3_3]*B[AFFINE_IDX_3_2];
- cell_3_3=A[AFFINE_IDX_3_0]*B[AFFINE_IDX_0_3]+A[AFFINE_IDX_3_1]*B[AFFINE_IDX_1_3]+A[AFFINE_IDX_3_2]*B[AFFINE_IDX_2_3]+A[AFFINE_IDX_3_3]*B[AFFINE_IDX_3_3];
- R[AFFINE_IDX_0_0]=cell_0_0;
- R[AFFINE_IDX_0_1]=cell_0_1;
- R[AFFINE_IDX_0_2]=cell_0_2;
- R[AFFINE_IDX_0_3]=cell_0_3;
- R[AFFINE_IDX_1_0]=cell_1_0;
- R[AFFINE_IDX_1_1]=cell_1_1;
- R[AFFINE_IDX_1_2]=cell_1_2;
- R[AFFINE_IDX_1_3]=cell_1_3;
- R[AFFINE_IDX_2_0]=cell_2_0;
- R[AFFINE_IDX_2_1]=cell_2_1;
- R[AFFINE_IDX_2_2]=cell_2_2;
- R[AFFINE_IDX_2_3]=cell_2_3;
- R[AFFINE_IDX_3_0]=cell_3_0;
- R[AFFINE_IDX_3_1]=cell_3_1;
- R[AFFINE_IDX_3_2]=cell_3_2;
- R[AFFINE_IDX_3_3]=cell_3_3;
- }
- /* Odie_Affine4x4_Inverse */
- int Odie_Affine4x4_Inverse(AFFINE r, AFFINE m){
- double d00, d01, d02, d03;
- double d10, d11, d12, d13;
- double d20, d21, d22, d23;
- double d30, d31, d32, d33;
- double m00, m01, m02, m03;
- double m10, m11, m12, m13;
- double m20, m21, m22, m23;
- double m30, m31, m32, m33;
- double D;
- m00 = m[AFFINE_IDX_0_0]; m01 = m[AFFINE_IDX_0_1]; m02 = m[AFFINE_IDX_0_2]; m03 = m[AFFINE_IDX_0_3];
- m10 = m[AFFINE_IDX_1_0]; m11 = m[AFFINE_IDX_1_1]; m12 = m[AFFINE_IDX_1_2]; m13 = m[AFFINE_IDX_1_3];
- m20 = m[AFFINE_IDX_2_0]; m21 = m[AFFINE_IDX_2_1]; m22 = m[AFFINE_IDX_2_2]; m23 = m[AFFINE_IDX_2_3];
- m30 = m[AFFINE_IDX_3_0]; m31 = m[AFFINE_IDX_3_1]; m32 = m[AFFINE_IDX_3_2]; m33 = m[AFFINE_IDX_3_3];
- d00 = m11*m22*m33 + m12*m23*m31 + m13*m21*m32 - m31*m22*m13 - m32*m23*m11 - m33*m21*m12;
- d01 = m10*m22*m33 + m12*m23*m30 + m13*m20*m32 - m30*m22*m13 - m32*m23*m10 - m33*m20*m12;
- d02 = m10*m21*m33 + m11*m23*m30 + m13*m20*m31 - m30*m21*m13 - m31*m23*m10 - m33*m20*m11;
- d03 = m10*m21*m32 + m11*m22*m30 + m12*m20*m31 - m30*m21*m12 - m31*m22*m10 - m32*m20*m11;
- d10 = m01*m22*m33 + m02*m23*m31 + m03*m21*m32 - m31*m22*m03 - m32*m23*m01 - m33*m21*m02;
- d11 = m00*m22*m33 + m02*m23*m30 + m03*m20*m32 - m30*m22*m03 - m32*m23*m00 - m33*m20*m02;
- d12 = m00*m21*m33 + m01*m23*m30 + m03*m20*m31 - m30*m21*m03 - m31*m23*m00 - m33*m20*m01;
- d13 = m00*m21*m32 + m01*m22*m30 + m02*m20*m31 - m30*m21*m02 - m31*m22*m00 - m32*m20*m01;
- d20 = m01*m12*m33 + m02*m13*m31 + m03*m11*m32 - m31*m12*m03 - m32*m13*m01 - m33*m11*m02;
- d21 = m00*m12*m33 + m02*m13*m30 + m03*m10*m32 - m30*m12*m03 - m32*m13*m00 - m33*m10*m02;
- d22 = m00*m11*m33 + m01*m13*m30 + m03*m10*m31 - m30*m11*m03 - m31*m13*m00 - m33*m10*m01;
- d23 = m00*m11*m32 + m01*m12*m30 + m02*m10*m31 - m30*m11*m02 - m31*m12*m00 - m32*m10*m01;
- d30 = m01*m12*m23 + m02*m13*m21 + m03*m11*m22 - m21*m12*m03 - m22*m13*m01 - m23*m11*m02;
- d31 = m00*m12*m23 + m02*m13*m20 + m03*m10*m22 - m20*m12*m03 - m22*m13*m00 - m23*m10*m02;
- d32 = m00*m11*m23 + m01*m13*m20 + m03*m10*m21 - m20*m11*m03 - m21*m13*m00 - m23*m10*m01;
- d33 = m00*m11*m22 + m01*m12*m20 + m02*m10*m21 - m20*m11*m02 - m21*m12*m00 - m22*m10*m01;
- D = m00*d00 - m01*d01 + m02*d02 - m03*d03;
- if (D == 0.0)
- {
- /* MatStack_Error("Singular matrix in MInvers."); */
- return TCL_ERROR;
- }
- r[AFFINE_IDX_0_0] = d00/D; r[AFFINE_IDX_0_1] = -d10/D; r[AFFINE_IDX_0_2] = d20/D; r[AFFINE_IDX_0_3] = -d30/D;
- r[AFFINE_IDX_1_0] = -d01/D; r[AFFINE_IDX_1_1] = d11/D; r[AFFINE_IDX_1_2] = -d21/D; r[AFFINE_IDX_1_3] = d31/D;
- r[AFFINE_IDX_2_0] = d02/D; r[AFFINE_IDX_2_1] = -d12/D; r[AFFINE_IDX_2_2] = d22/D; r[AFFINE_IDX_2_3] = -d32/D;
- r[AFFINE_IDX_3_0] = -d03/D; r[AFFINE_IDX_3_1] = d13/D; r[AFFINE_IDX_3_2] = -d23/D; r[AFFINE_IDX_3_3] = d33/D;
- return TCL_OK;
- }
- /* Odie_Affine_From_Normal */
- static void Odie_Affine_From_Normal(AFFINE RESULT,VectorXYZ NORMAL){
- double c,s,C;
- VectorXYZ axis;
- /* If UP and NORMAL are identical (or nearly identical) no rotation */
- if (VectorXYZ_IsZero(NORMAL)) {
- Odie_Affine4x4_Identity(RESULT);
- return;
- }
- if (VectorXYZ_SamePoint(Odie_Up_Direction,NORMAL)) {
- Odie_Affine4x4_Identity(RESULT);
- return;
- }
- VectorXYZ_Cross_Product(axis,Odie_Up_Direction,NORMAL);
- VectorXYZ_Normalize(axis);
- c=VectorXYZ_Dot_Product(Odie_Up_Direction,NORMAL);
- s=sqrt(1-c*c);
- C=1-c;
- RESULT[AFFINE_IDX_0_0]=axis[X_IDX]*axis[X_IDX]*C+c;
- RESULT[AFFINE_IDX_0_1]=axis[X_IDX]*axis[Y_IDX]*C-axis[Z_IDX]*s;
- RESULT[AFFINE_IDX_0_2]=axis[X_IDX]*axis[Z_IDX]*C+axis[Y_IDX]*s;
- RESULT[AFFINE_IDX_0_3]=0.0;
- RESULT[AFFINE_IDX_1_0]=axis[Y_IDX]*axis[X_IDX]*C+axis[Z_IDX]*s;
- RESULT[AFFINE_IDX_1_1]=axis[Y_IDX]*axis[Y_IDX]*C+c;
- RESULT[AFFINE_IDX_1_2]=axis[Y_IDX]*axis[Z_IDX]*C-axis[X_IDX]*s;
- RESULT[AFFINE_IDX_1_3]=0.0;
- RESULT[AFFINE_IDX_2_0]=axis[Z_IDX]*axis[X_IDX]*C-axis[Y_IDX]*s;
- RESULT[AFFINE_IDX_2_1]=axis[Z_IDX]*axis[Y_IDX]*C+axis[X_IDX]*s;
- RESULT[AFFINE_IDX_2_2]=axis[Z_IDX]*axis[Z_IDX]*C+c;
- RESULT[AFFINE_IDX_2_3]=0.0;
- RESULT[AFFINE_IDX_3_0]=0.0;
- RESULT[AFFINE_IDX_3_1]=0.0;
- RESULT[AFFINE_IDX_3_2]=0.0;
- RESULT[AFFINE_IDX_3_3]=1.0;
- }
- /* VectorXY_BBOX_Copy */
- static inline void VectorXY_BBOX_Copy(BBOXXY dest,BBOXXY src){ dest[BBOX_X0_IDX]=src[BBOX_X0_IDX];
- dest[BBOX_Y1_IDX]=src[BBOX_Y1_IDX];
- dest[BBOX_X1_IDX]=src[BBOX_X1_IDX];
- dest[BBOX_X1_IDX]=src[BBOX_X1_IDX];
- }
- /* VectorXY_BBOX_Reset */
- static inline void VectorXY_BBOX_Reset(BBOXXY R){
- R[BBOX_X0_IDX]=R[BBOX_Y0_IDX]=1e99;
- R[BBOX_Y1_IDX]=R[BBOX_X1_IDX]=-1e99;
- }
- /* VectorXY_IsBetween_BBOX */
- static inline int VectorXY_IsBetween_BBOX(VectorXY POINT,VectorXY A,VectorXY B){
- if (POINT[X_IDX]<A[X_IDX] && POINT[X_IDX]<B[X_IDX]) return 0;
- if (POINT[X_IDX]>A[X_IDX] && POINT[X_IDX]>B[X_IDX]) return 0;
- if (POINT[Y_IDX]<A[Y_IDX] && POINT[Y_IDX]<B[Y_IDX]) return 0;
- if (POINT[Y_IDX]>A[Y_IDX] && POINT[Y_IDX]>B[Y_IDX]) return 0;
- return 1;
- }
- /* VectorXY_Within_BBOX */
- static inline int VectorXY_Within_BBOX(VectorXY POINT,BBOXXY bbox){
- if(POINT[X_IDX]<bbox[BBOX_X0_IDX]) return 0;
- if(POINT[Y_IDX]>bbox[BBOX_Y1_IDX]) return 0;
- if(POINT[X_IDX]>bbox[BBOX_X1_IDX]) return 0;
- if(POINT[Y_IDX]<bbox[BBOX_Y0_IDX]) return 0;
- return 1;
- }
- /* XY_Within_BBOX */
- static inline int XY_Within_BBOX(double x, double y,BBOXXY bbox){
- if(x<bbox[BBOX_X0_IDX]) return 0;
- if(y>bbox[BBOX_Y1_IDX]) return 0;
- if(x>bbox[BBOX_X1_IDX]) return 0;
- if(y<bbox[BBOX_Y0_IDX]) return 0;
- return 1;
- }
- /* VectorXY_BBOX_Measure */
- static inline void VectorXY_BBOX_Measure(VectorXY POINT,BBOXXY bbox){
- if(POINT[X_IDX]<bbox[BBOX_X0_IDX]) bbox[BBOX_X0_IDX]=POINT[X_IDX];
- if(POINT[Y_IDX]>bbox[BBOX_Y1_IDX]) bbox[BBOX_Y1_IDX]=POINT[Y_IDX];
- if(POINT[X_IDX]>bbox[BBOX_X1_IDX]) bbox[BBOX_X1_IDX]=POINT[X_IDX];
- if(POINT[Y_IDX]<bbox[BBOX_Y0_IDX]) bbox[BBOX_Y0_IDX]=POINT[Y_IDX];
- }
- /* BBOX_BBOX_Intersect */
- static inline int BBOX_BBOX_Intersect(BBOXXY A,BBOXXY B){
- int a_inside_b=0;
- int b_inside_a=0;
- int i,j;
- if(A[BBOX_X0_IDX]>=B[BBOX_X0_IDX] && A[BBOX_X1_IDX]<=B[BBOX_X1_IDX]) {
- if(A[BBOX_Y1_IDX]<=B[BBOX_Y1_IDX] && A[BBOX_Y0_IDX]>=B[BBOX_Y0_IDX]) {
- a_inside_b=1;
- }
- }
- if(B[BBOX_X0_IDX]>=A[BBOX_X0_IDX] && B[BBOX_X1_IDX]<=A[BBOX_X1_IDX]) {
- if(B[BBOX_Y1_IDX]<=A[BBOX_Y1_IDX] && B[BBOX_Y0_IDX]>=A[BBOX_Y0_IDX]) {
- b_inside_a=1;
- }
- }
- if(a_inside_b && b_inside_a) {
- return 2;
- }
- if(a_inside_b) {
- return 3;
- }
- if(b_inside_a) {
- return 4;
- }
- if(XY_Within_BBOX(B[BBOX_X0_IDX],B[BBOX_Y1_IDX],A)) return 1;
- if(XY_Within_BBOX(B[BBOX_X0_IDX],B[BBOX_Y0_IDX],A)) return 1;
- if(XY_Within_BBOX(B[BBOX_X1_IDX],B[BBOX_Y1_IDX],A)) return 1;
- if(XY_Within_BBOX(B[BBOX_X1_IDX],B[BBOX_Y0_IDX],A)) return 1;
- if(XY_Within_BBOX(A[BBOX_X0_IDX],A[BBOX_Y1_IDX],B)) return 1;
- if(XY_Within_BBOX(A[BBOX_X0_IDX],A[BBOX_Y0_IDX],B)) return 1;
- if(XY_Within_BBOX(A[BBOX_X1_IDX],A[BBOX_Y1_IDX],B)) return 1;
- if(XY_Within_BBOX(A[BBOX_X1_IDX],A[BBOX_Y0_IDX],B)) return 1;
- return 0;
- }
- /* *Matrix_To_quaternion */
- const char *Matrix_To_quaternion(Odie_MatrixObj *matrix,int form){
- if(matrix->form==form) {
- return NULL;
- }
- if(Matrix_To_cartesian(matrix,MATFORM_cartesian)) {
- return "Cannot convert to spherical";
- }
- if(matrix->form==MATFORM_cartesian) {
- odiemath_cartesian_to_spherical(matrix->matrix,matrix->matrix);
- }
- matrix->form=form;
- matrix->rows=4;
- matrix->cols=1;
- return NULL;
- }
- /* *Quaternion_To_TclObj */
- Tcl_Obj *Quaternion_To_TclObj(QUATERNION R){
- Odie_MatrixObj *RESULT;
- RESULT=Odie_MatrixObj_Create(MATFORM_quaternion);
- RESULT->matrix[QW_IDX]=R[QW_IDX];
- RESULT->matrix[QX_IDX]=R[QX_IDX];
- RESULT->matrix[QY_IDX]=R[QY_IDX];
- RESULT->matrix[QZ_IDX]=R[QZ_IDX];
- return Matrix_To_TclObj(RESULT);
- }
- /* Odie_GetQuaternionFromTclObj */
- int Odie_GetQuaternionFromTclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,QUATERNION R){
- Tcl_Obj **elemPtrs;
- int cols,i;
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&MatrixObj_setFromAnyProc) {
- /*
- ** Object is a matrix
- */
- const char *err;
- Odie_MatrixObj *value=objPtr->internalRep.otherValuePtr;
- err=Matrix_To_cartesian(value,MATFORM_quaternion);
- if(err) {
- Tcl_AppendResult(interp,err,NULL);
- return TCL_ERROR;
- }
- R[QW_IDX]=value->matrix[QW_IDX];
- R[QX_IDX]=value->matrix[QX_IDX];
- R[QY_IDX]=value->matrix[QY_IDX];
- R[QZ_IDX]=value->matrix[QZ_IDX];
- return TCL_OK;
- }
- }
- /* Step one, Measure the matrix */
- if(Tcl_ListObjGetElements(interp, objPtr, &cols, &elemPtrs)) return TCL_ERROR;
- if(cols<4) {
- Tcl_SetObjResult(interp,Tcl_NewStringObj("Needs 3 columns",-1));
- return TCL_ERROR;
- }
- for(i=0;i<4;i++) {
- double temp;
- if(Tcl_GetDoubleFromObj(interp, elemPtrs[i], &temp)) return TCL_ERROR;
- R[i]=temp;
- }
- return TCL_OK;
- }
- /* Quaternion_Add */
- void Quaternion_Add(QUATERNION r, QUATERNION p, QUATERNION q){
- r[QW_IDX]=p[QW_IDX]+q[QW_IDX];
- r[QX_IDX]=p[QX_IDX]+q[QX_IDX];
- r[QY_IDX]=p[QY_IDX]+q[QY_IDX];
- r[QZ_IDX]=p[QZ_IDX]+q[QZ_IDX];
- }
- /* Quaternion_Subtract */
- void Quaternion_Subtract(QUATERNION r, QUATERNION p, QUATERNION q){
- r[QW_IDX]=p[QW_IDX]-q[QW_IDX];
- r[QX_IDX]=p[QX_IDX]-q[QX_IDX];
- r[QY_IDX]=p[QY_IDX]-q[QY_IDX];
- r[QZ_IDX]=p[QZ_IDX]-q[QZ_IDX];
- }
- /* Quaternion_Multiply */
- void Quaternion_Multiply(QUATERNION r, QUATERNION p, QUATERNION q){
- double t0, t1, t2;
- t0 = p[QW_IDX] * q[QW_IDX] - p[QX_IDX] * q[QX_IDX] - p[QY_IDX] * q[QY_IDX] - p[QZ_IDX] * q[QZ_IDX];
- t1 = p[QW_IDX] * q[QX_IDX] + p[QX_IDX] * q[QW_IDX] + p[QY_IDX] * q[QZ_IDX] - p[QZ_IDX] * q[QY_IDX];
- t2 = p[QW_IDX] * q[QY_IDX] + p[QY_IDX] * q[QW_IDX] + p[QZ_IDX] * q[QX_IDX] - p[QX_IDX] * q[QZ_IDX];
- r[QZ_IDX] = p[QW_IDX] * q[QZ_IDX] + p[QZ_IDX] * q[QW_IDX] + p[QX_IDX] * q[QY_IDX] - p[QY_IDX] * q[QX_IDX];
- r[QW_IDX] = t0;
- r[QX_IDX] = t1;
- r[QY_IDX] = t2;
- }
- /* Quaternion_Divide */
- void Quaternion_Divide(QUATERNION r, QUATERNION p, QUATERNION q){
- QUATERNION Q,t,s;
- double a;
- Q[QW_IDX]=q[QW_IDX];
- Q[QX_IDX]=-q[QX_IDX];
- Q[QY_IDX]=-q[QY_IDX];
- Q[QZ_IDX]=-q[QZ_IDX];
- Quaternion_Multiply(t,p,Q);
- Quaternion_Multiply(s,Q,Q);
- a=1.0/s[QW_IDX];
- r[QW_IDX]=t[QW_IDX]*a;
- r[QX_IDX]=t[QX_IDX]*a;
- r[QY_IDX]=t[QY_IDX]*a;
- r[QZ_IDX]=t[QY_IDX]*a;
- }
- /* Quaternion_Square_Root */
- void Quaternion_Square_Root(QUATERNION s, QUATERNION q){
- double len,m;
- double a,b;
- QUATERNION r;
- len=sqrt(q[QW_IDX]*q[QW_IDX]+q[QX_IDX]*q[QX_IDX]+q[QY_IDX]*q[QY_IDX]);
- if(len==0) {
- s[QW_IDX]=s[QX_IDX]=s[QY_IDX]=s[QZ_IDX]=0.0;
- return;
- }
- r[QW_IDX]=q[QW_IDX]*1.0;
- r[QX_IDX]=q[QX_IDX]*1.0;
- r[QY_IDX]=q[QY_IDX]*1.0;
- r[QZ_IDX]=0.0;
- m=1.0/sqrt(r[QW_IDX]*r[QW_IDX]+r[QX_IDX]*r[QX_IDX]);
- a=sqrt((1.0+r[QY_IDX])*0.5);
- b=sqrt((1.0-r[QY_IDX])*0.5);
- s[QW_IDX]=sqrt(len)*b*r[QW_IDX]*m;
- s[QX_IDX]=sqrt(len)*b*r[QX_IDX]*m;
- s[QY_IDX]=sqrt(len)*a;
- s[QZ_IDX]=q[QZ_IDX];
- }
- /* Quaternion_Square */
- void Quaternion_Square(QUATERNION r, QUATERNION q){
- double a;
- a=2.0*q[QW_IDX];
- r[QW_IDX]=q[QW_IDX]*q[QW_IDX]-q[QX_IDX]*q[QX_IDX]-q[QY_IDX]*q[QY_IDX]-q[QZ_IDX]*q[QZ_IDX];
- r[QX_IDX]=a*q[QX_IDX];
- r[QY_IDX]=a*q[QY_IDX];
- r[QZ_IDX]=a*q[QZ_IDX];
- }
- /* EulerRotation_To_Quaternion */
- void EulerRotation_To_Quaternion(QUATERNION q,double heading, double attitude, double bank){
- // Assuming the angles are in radians.
- double c1 = cos(heading*0.5);
- double s1 = sin(heading*0.5);
- double c2 = cos(attitude*0.5);
- double s2 = sin(attitude*0.5);
- double c3 = cos(bank*0.5);
- double s3 = sin(bank*0.5);
- double c1c2 = c1*c2;
- double s1s2 = s1*s2;
- q[QW_IDX] =c1c2*c3 - s1s2*s3;
- q[QX_IDX] =c1c2*s3 + s1s2*c3;
- q[QY_IDX] =s1*c2*c3 + c1*s2*s3;
- q[QZ_IDX] =c1*s2*c3 - s1*c2*s3;
- }
- /* VectorXYZ_Rotate_by_Quaternion */
- void VectorXYZ_Rotate_by_Quaternion(VECTORXYZ r, QUATERNION p, VECTORXYZ A){
- double w=p[QW_IDX]; // real part of quaternion
- double x=p[QX_IDX]; // imaginary i part of quaternion
- double y=p[QY_IDX]; // imaginary j part of quaternion
- double z=p[QZ_IDX]; // imaginary k part of quaternion
- double px=A[X_IDX];
- double py=A[Y_IDX];
- double pz=A[Z_IDX];
- r[X_IDX] = w*w*px + 2*y*w*pz - 2*z*w*py + x*x*px + 2*y*x*py + 2*z*x*pz - z*z*px - y*y*px;
- r[Y_IDX] = 2*x*y*px + y*y*py + 2*z*y*pz + 2*w*z*px - z*z*py + w*w*py - 2*x*w*pz - x*x*py;
- r[Z_IDX] = 2*x*z*px + 2*y*z*py + z*z*pz - 2*w*y*px - y*y*pz + 2*w*x*py - x*x*pz + w*w*pz;
- }
- /* Quaternion_To_EulerRotation */
- void Quaternion_To_EulerRotation (VECTORXYZ r, QUATERNION p){
- double sqw = p[QW_IDX]*p[QW_IDX];
- double sqx = p[QX_IDX]*p[QX_IDX];
- double sqy = p[QY_IDX]*p[QY_IDX];
- double sqz = p[QZ_IDX]*p[QZ_IDX];
- double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
- double test = p[QX_IDX]*p[QY_IDX] + p[QZ_IDX]*p[QW_IDX];
- if (test > 0.499*unit) { // singularity at north pole
- r[EULER_HEADING] = 2 * atan2(p[QX_IDX],p[QW_IDX]);
- r[EULER_ATTITUDE] = M_PI*0.5;
- r[EULER_BANK] = 0;
- return;
- }
- if (test < -0.499*unit) { // singularity at south pole
- r[EULER_HEADING] = -2 * atan2(p[QX_IDX],p[QW_IDX]);
- r[EULER_ATTITUDE] = M_PI*-0.5;
- r[EULER_BANK] = 0;
- return;
- }
- r[EULER_HEADING] = atan2(2*p[QY_IDX]*p[QW_IDX]-2*p[QX_IDX]*p[QZ_IDX] , sqx - sqy - sqz + sqw);
- r[EULER_ATTITUDE] = asin(2*test/unit);
- r[EULER_BANK] = atan2(2*p[QX_IDX]*p[QW_IDX]-2*p[QY_IDX]*p[QZ_IDX] , -sqx + sqy - sqz + sqw);
- }
- /* Quaternion_From_Normal */
- static inline void Quaternion_From_Normal(QUATERNION RESULT,VectorXYZ from,VectorXYZ to){
- VectorXYZ H;
- VectorXYZ_Add(H,from,to);
- /* Special case?
- if(VectorXYZ_IsZero(H)) {
- RESULT[QW_IDX]=0.0;
- RESULT[QX_IDX]=1.0;
- RESULT[QY_IDX]=0.0;
- RESULT[QZ_IDX]=0.0;
- }
- */
- VectorXYZ_Normalize(H);
- RESULT[QW_IDX]=VectorXYZ_Dot_Product(from,H);
- RESULT[QX_IDX]=from[Y_IDX]*H[Z_IDX] - from[Z_IDX]*H[Y_IDX];
- RESULT[QY_IDX]=from[Z_IDX]*H[X_IDX] - from[X_IDX]*H[Z_IDX];
- RESULT[QZ_IDX]=from[X_IDX]*H[Y_IDX] - from[Y_IDX]*H[X_IDX];
- }
- /* *Odie_Matrix_To_Fit */
- static Odie_MatrixObj *Odie_Matrix_To_Fit(Odie_MatrixObj *A,Odie_MatrixObj *B){
- Odie_MatrixObj *C;
- int size_a;
- int size_b;
- if(A->rows==B->rows && A->cols==B->cols) {
- if(A->form && A->form==B->form) {
- C=Odie_MatrixObj_Create(A->form);
- } else {
- C=Odie_MatrixObj_Create_NXN(A->rows,A->cols);
- }
- return C;
- }
- size_a=A->rows*A->cols;
- size_b=B->rows*B->cols;
- if(size_a<size_b) {
- C=Odie_MatrixObj_Create_NXN(size_b,1);
- } else {
- C=Odie_MatrixObj_Create_NXN(size_a,1);
- }
- return C;
- }
- /* Vector_GridScaler */
- static inline double Vector_GridScaler(double x,double grid,double grain){
- double q;
- q=grid*round(x/grid);
- if((x-q)>grain) {
- q+=grain;
- }
- return q;
- }
- /* Vector2d_SamePoint */
- inline extern int Vector2d_SamePoint(double x0, double y0, double x1, double y1){
- /*
- ** Return TRUE if x0,y0 is the same point as x1,y1
- */
- return floatCompare(x0,x1)==0 && floatCompare(y0,y1)==0;
- }
- /* Vector2d_IsColinear */
- inline extern int Vector2d_IsColinear(double x1,double y1,double x2,double y2,double x3,double y3){
- /* Detect of two lines are colinear */
- double c=(x3-x1)*(y2-y1)-(y3-y1)*(x2-x1);
- if(fabs(c) < __FLT_EPSILON__) return 1;
- return 0;
- }
- /* Vector2d_LineLineCoincident */
- inline extern int Vector2d_LineLineCoincident(
- double ax1, double ay1,
- double ax2, double ay2,
- double bx1, double by1,
- double bx2, double by2){
- double x,y;
- int c=0;
- /* Check if wall completely wraps other wall */
- if(Vector2d_SamePoint(ax1,ay1,bx1,by1)) {
- if(Vector2d_SamePoint(ax2,ay2,bx2,by2)) return 6;
- if(Vector2d_PointIsOnSegment(ax2,ay2,bx1,by1,bx2,by2)) return 2;
- return 0;
- }
- if(Vector2d_SamePoint(ax2,ay2,bx1,by1)) {
- if(Vector2d_SamePoint(ax1,ay1,bx2,by2)) return 6;
- if(Vector2d_PointIsOnSegment(ax1,ay1,bx1,by1,bx2,by2)) return 4;
- return 0;
- }
- if(Vector2d_SamePoint(ax1,ay1,bx2,by2)) {
- if(Vector2d_PointIsOnSegment(ax2,ay2,bx1,by1,bx2,by2)) return 2;
- return 0;
- }
- if(Vector2d_SamePoint(ax2,ay2,bx2,by2)) {
- if(Vector2d_PointIsOnSegment(ax1,ay1,bx1,by1,bx2,by2)) return 4;
- return 0;
- }
- c=ODIE_Math_LineLineIntersect(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2,&x,&y);
- if(c) {
- if(Vector2d_SamePoint(ax1,ay1,x,y)) {
- return 0;
- }
- if(Vector2d_SamePoint(ax2,ay2,x,y)) {
- return 0;
- }
- }
- return c;
- }
- /* ODIE_Math_LineLineIntersect */
- int ODIE_Math_LineLineIntersect(
- double ax1, double ay1,
- double ax2, double ay2,
- double bx1, double by1,
- double bx2, double by2,
- double *x, double *y){
- /*
- ** Detect the intersection of two lines
- ** Adapted from: http://paulbourke.net/geometry/lineline2d/pdb.c
- */
- double mua,mub;
- double denom,numera,numerb;
- denom = (by2-by1) * (ax2-ax1) - (bx2-bx1) * (ay2-ay1);
- numera = (bx2-bx1) * (ay1-by1) - (by2-by1) * (ax1-bx1);
- numerb = (ax2-ax1) * (ay1-by1) - (ay2-ay1) * (ax1-bx1);
- /* Are the line parallel */
- if (ODIE_Real_Is_Zero(denom)) {
- if (ODIE_Real_Is_Zero(numera) && ODIE_Real_Is_Zero(numerb)) {
- /* Are the line coincident? */
- int within=1;
- if(ax2>ax1) {
- if(bx1>ax2 && bx2>ax2) {
- within=0;
- } else if(bx1<ax1 && bx2<ax1) {
- within=0;
- }
- } else {
- if(bx1>ax1 && bx2>ax1) {
- within=0;
- } else if(bx1<ax2 && bx2<ax2) {
- within=0;
- }
- }
- if(ay2>ay1) {
- if(by1>ay2 && by2>ay2) {
- within=0;
- } else if(by1<ay1 && by2<ay1) {
- within=0;
- }
- } else {
- if(by1>ay1 && by2>ay1) {
- within=0;
- } else if(by1<ay2 && by2<ay2) {
- within=0;
- }
- }
- if(within) {
- *x = (ax1 + ax2) / 2;
- *y = (ay1 + ay2) / 2;
- return(2);
- }
- }
- *x = 0;
- *y = 0;
- return(0);
- }
- /* Is the intersection along the the segments */
- mua = numera / denom;
- mub = numerb / denom;
- if (mua < 0 || mua > 1 || mub < 0 || mub > 1) {
- *x = 0;
- *y = 0;
- return(0);
- }
- *x = ax1 + mua * (ax2 - ax1);
- *y = ay1 + mua * (ay2 - ay1);
- return(1);
- }
- /* Vector2d_PointIsOnSegment */
- static inline int Vector2d_PointIsOnSegment(double x,double y,double x1,double y1,double x2,double y2){
- /* Returns:
- ** 0 - not on segment
- ** 1 - along segment
- ** 2 - endpoint of segment
- */
- /* Bounding box check */
- if(x1>x2) {
- if(x>(x1+OdieGrain)) return 0;
- if(x<(x2-OdieGrain)) return 0;
- } else {
- if(x>(x2+OdieGrain)) return 0;
- if(x<(x1-OdieGrain)) return 0;
- }
- if(y1>y2) {
- if(y>(y1+OdieGrain)) return 0;
- if(y<(y2-OdieGrain)) return 0;
- } else {
- if(y>(y2+OdieGrain)) return 0;
- if(y<(y1-OdieGrain)) return 0;
- }
- if(Vector2d_SamePoint(x,y,x1,y1)) return 2;
- if(Vector2d_SamePoint(x,y,x2,y2)) return 2;
- /* Detect of two lines are colinear */
- if (Vector2d_IsColinear(x,y,x1,y1,x2,y2)) {
- return 1;
- }
- return 0;
- }
- /* ODIE_Math_LineCircleIntersect */
- int ODIE_Math_LineCircleIntersect(
- double p1_x, double p1_y,
- double p2_x, double p2_y,
- double sc_x, double sc_y,
- double r,
- double *mu1, double *mu2){
- /*
- ** Detect the intersection of a line and a circle
- ** Adapted from: http://http://paulbourke.net/geometry/circlesphere/raysphere.c
- */
- double a,b,c;
- double bb4ac;
- double dp_x,dp_y;
- *mu1 = 0;
- *mu2 = 0;
- dp_x = p2_x - p1_x;
- dp_y = p2_y - p1_y;
- a = dp_x * dp_x + dp_y * dp_y;
- b = 2 * (dp_x * (p1_x - sc_x) + dp_y * (p1_y - sc_y));
- c = sc_x * sc_x + sc_y * sc_y;
- c += p1_x * p1_x + p1_y * p1_y;
- c -= 2 * (sc_x * p1_x + sc_y * p1_y);
- c -= r * r;
- bb4ac = b * b - 4 * a * c;
- if (ODIE_Real_Is_Zero(a) || bb4ac < 0) {
- return(0);
- }
- *mu1 = (-b + sqrt(bb4ac)) / (2 * a);
- *mu2 = (-b - sqrt(bb4ac)) / (2 * a);
- return(1);
- }
- /* Vector3d_SamePoint */
- inline extern int Vector3d_SamePoint(double x0, double y0, double z0, double x1, double y1, double z1){
- /*
- ** Return TRUE if x0,y0 is the same point as x1,y1
- */
- return floatCompare(x0,x1)==0 && floatCompare(y0,y1)==0 && floatCompare(z0,z1)==0;
- }
- /* odiemath_polar_to_vec2 */
- void odiemath_polar_to_vec2(VECTORXY A,VECTORXY R){
- /*
- ** Make a copy of the input matrix in case we are outputing back
- ** to the same pointer
- */
- double radius,theta;
- radius=A[RADIUS];
- theta=A[THETA];
- R[X_IDX]=radius*cos(theta);
- R[Y_IDX]=radius*sin(theta);
- }
- /* odiemath_vec2_to_polar */
- void odiemath_vec2_to_polar(VECTORXY A,VECTORXY R){
- double x,y;
- x=A[X_IDX];
- y=A[Y_IDX];
- R[RADIUS]=sqrt(x*x + y*y);
- R[THETA] =atan2(y,x);
- }
- /* *Matrix_To_vector_xy */
- const char *Matrix_To_vector_xy(Odie_MatrixObj *matrix,int form){
- if(matrix->form==form) {
- return NULL;
- }
- switch(matrix->form) {
- case MATFORM_vector_xy:
- return TCL_OK;
- case MATFORM_vector_xyz: {
- return NULL;
- }
- case MATFORM_cylindrical: {
- odiemath_vec2_to_polar(matrix->matrix,matrix->matrix);
- matrix->form=MATFORM_cartesian;
- return NULL;
- }
- }
- return Matrix_To_cartesian(matrix,MATFORM_vector_xy);
- }
- /* *VectorXY_To_TclObj */
- Tcl_Obj *VectorXY_To_TclObj(VectorXY R){
- Odie_MatrixObj *RESULT;
- RESULT=Odie_MatrixObj_Create(MATFORM_vector_xy);
- RESULT->matrix[X_IDX]=R[X_IDX];
- RESULT->matrix[Y_IDX]=R[Y_IDX];
- return Matrix_To_TclObj(RESULT);
- }
- /* Odie_GetVectorXYFromTclObj */
- int Odie_GetVectorXYFromTclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,VectorXY R){
- Tcl_Obj **elemPtrs;
- int cols,i;
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&MatrixObj_setFromAnyProc) {
- /*
- ** Object is a matrix
- */
- const char *err;
- Odie_MatrixObj *value=objPtr->internalRep.otherValuePtr;
- err=Matrix_To_cartesian(value,MATFORM_vector_xy);
- if(err) {
- Tcl_AppendResult(interp,err,NULL);
- return TCL_ERROR;
- }
- R[X_IDX]=value->matrix[X_IDX];
- R[Y_IDX]=value->matrix[Y_IDX];
- return TCL_OK;
- }
- }
- /* Step one, Measure the matrix */
- if(Tcl_ListObjGetElements(interp, objPtr, &cols, &elemPtrs)) return TCL_ERROR;
- for(i=0;i<2;i++) {
- double temp;
- if(cols<=i) {
- R[i]=0.0;
- } else {
- if(Tcl_GetDoubleFromObj(interp, elemPtrs[i], &temp)) return TCL_ERROR;
- R[i]=temp;
- }
- }
- return TCL_OK;
- }
- /* VectorXY_GridAlign */
- static inline void VectorXY_GridAlign(VECTORXYZ A,double grid){
- double x,q,grain;
- grain=grid*0.5;
- if(grid<=0) return;
- A[X_IDX]=Vector_GridScaler(A[X_IDX],grid,grain);
- A[Y_IDX]=Vector_GridScaler(A[Y_IDX],grid,grain);
- }
- /* VectorXY_SamePoint */
- inline extern int VectorXY_SamePoint(VectorXY A, VectorXY B){
- if(fabs(B[X_IDX]-A[X_IDX])>Vector_Tolerance) return 0;
- if(fabs(B[Y_IDX]-A[Y_IDX])>Vector_Tolerance) return 0;
- return 1;
- }
- /* VectorXY_SameGridPoint */
- inline extern int VectorXY_SameGridPoint(VectorXY A, VectorXY B,double grid){
- if(fabs(B[X_IDX]-A[X_IDX])>grid) return 0;
- if(fabs(B[Y_IDX]-A[Y_IDX])>grid) return 0;
- return 1;
- }
- /* VectorXY_Add */
- inline extern void VectorXY_Add(VECTORXY C,VECTORXY A,VECTORXY B){
- C[X_IDX]=B[X_IDX]+A[X_IDX];
- C[Y_IDX]=B[Y_IDX]+A[Y_IDX];
- }
- /* VectorXY_Subtract */
- inline extern void VectorXY_Subtract(VECTORXY C,VECTORXY A,VECTORXY B){
- C[X_IDX]=A[X_IDX]-B[X_IDX];
- C[Y_IDX]=A[Y_IDX]-B[Y_IDX];
- }
- /* VectorXY_Midpoint */
- static inline void VectorXY_Midpoint(VECTORXY C,VECTORXY A,VECTORXY B){
- C[X_IDX]=(B[X_IDX]-A[X_IDX])*0.5+A[X_IDX];
- C[Y_IDX]=(B[Y_IDX]-A[Y_IDX])*0.5+A[Y_IDX];
- }
- /* VectorXY_Normalize */
- inline extern void VectorXY_Normalize(VECTORXY A){
- double length=sqrt(A[X_IDX]*A[X_IDX]+A[Y_IDX]*A[Y_IDX]);
- if(length < __FLT_EPSILON__ ) {
- return;
- }
- A[X_IDX]/=length;
- A[Y_IDX]/=length;
- }
- /* VectorXY_Round */
- inline extern void VectorXY_Round(VECTORXY A){
- A[X_IDX]=round(A[X_IDX]);
- A[Y_IDX]=round(A[Y_IDX]);
- }
- /* VectorXY_Set */
- inline extern void VectorXY_Set(VECTORXY A,VECTORXY B){
- A[X_IDX]=B[X_IDX];
- A[Y_IDX]=B[Y_IDX];
- }
- /* VectorXY_crossProduct */
- inline extern double VectorXY_crossProduct(VectorXY A, VectorXY B, VectorXY P){
- double r = (A[Y_IDX]-B[Y_IDX])*(P[X_IDX]-B[X_IDX]) + (B[X_IDX]-A[X_IDX])*(P[Y_IDX]-B[Y_IDX]);
- if(fabs(r) < __FLT_EPSILON__ ) {
- return 0.0;
- }
- return r;
- }
- /* VectorXY_Dot_Product */
- inline extern double VectorXY_Dot_Product(VectorXY A, VectorXY B,VectorXY C){
- double r=(A[X_IDX]-B[X_IDX])*(C[X_IDX]-B[X_IDX])+(A[Y_IDX]-B[Y_IDX])*(C[Y_IDX]-B[Y_IDX]);
- if(fabs(r) < __FLT_EPSILON__ ) {
- return 0.0;
- }
- return r;
- }
- /* VectorXY_BendDirection */
- inline extern int VectorXY_BendDirection(VectorXY A, VectorXY B, VectorXY C){
- /*
- ** Consider traveling from VectorXY A to B to C. If you have to make
- ** a left-turn at B, then this routine returns -1. If C is on the
- ** same line as A and B then return 0. If you make a right turn
- ** at B in order to reach C then return +1.
- */
- /* Algorithm: Rotate AB 90 degrees counter-clockwise. Take
- ** the dot product with BP. The dot produce will be the product
- ** of two (non-negative) magnitudes and the cosine of the angle. So if
- ** the dot product is positive, the bend is to the left, or to the right if
- ** the dot product is negative.
- */
- double r = (A[Y_IDX]-B[Y_IDX])*(C[X_IDX]-B[X_IDX]) + (B[X_IDX]-A[X_IDX])*(C[Y_IDX]-B[Y_IDX]);
- if(fabs(r) < __FLT_EPSILON__ ) return 0;
- if(r>0.0) return -1;
- return 1;
- }
- /* VectorXY_strictlyRightOf */
- inline extern int VectorXY_strictlyRightOf(VectorXY A, VectorXY B, VectorXY P){
- /*
- ** This is a variation on rightOf(). Return 0 only if BP is a continuation
- ** of the line AB. If BP doubles back on AB then return -1.
- */
- int c = VectorXY_BendDirection(A,B,P);
- if( c==0 ){
- double r = (A[X_IDX]-B[X_IDX])*(P[X_IDX]-B[X_IDX]) + (A[Y_IDX]-B[Y_IDX])*(P[Y_IDX]-B[Y_IDX]);
- c = r<0.0 ? +1 : -1;
- }
- return c;
- }
- /* VectorXY_intersect */
- inline extern int VectorXY_intersect(VectorXY A, VectorXY B, VectorXY C, VectorXY D){
- /*
- ** Return TRUE if segments AB and CD intersect
- */
- return VectorXY_BendDirection(A,B,C)*VectorXY_BendDirection(A,B,D)<0 && VectorXY_BendDirection(C,D,A)*VectorXY_BendDirection(C,D,B)<0;
- }
- /* VectorXY_angleOf */
- inline extern double VectorXY_angleOf(VectorXY A, VectorXY B, VectorXY C){
- /*
- ** Compute angle ABC measured counter-clockwise from AB. Return the
- ** result.
- **
- ** This does not need to be a true angular measure as long as it is
- ** monotonically increasing.
- */
- double a1, a2, a3;
- if( VectorXY_SamePoint(A,C) ){
- return M_PI;
- }
- a1 = atan2(B[Y_IDX] - A[Y_IDX], B[X_IDX] - A[X_IDX]);
- a2 = atan2(C[Y_IDX] - B[Y_IDX], C[X_IDX] - B[X_IDX]);
- a3 = a2-a1;
- if( a3>M_PI ) a3 -= 2.0*M_PI;
- if( a3<=-M_PI ) a3 += 2.0*M_PI;
- return a3;
- }
- /* VectorXY_Angle_Three_Point */
- inline extern double VectorXY_Angle_Three_Point(VectorXY A, VectorXY B, VectorXY C){
- /*
- ** Compute angle ABC measured counter-clockwise from AB. Return the
- ** result.
- **
- ** This does not need to be a true angular measure as long as it is
- ** monotonically increasing.
- */
- double a1, a2, a3;
- if( VectorXY_SamePoint(A,C) ){
- return M_PI;
- }
- a1 = atan2(B[Y_IDX] - A[Y_IDX], B[X_IDX] - A[X_IDX]);
- a2 = atan2(C[Y_IDX] - B[Y_IDX], C[X_IDX] - B[X_IDX]);
- a3 = a2-a1;
- if( a3>M_PI ) a3 -= 2.0*M_PI;
- if( a3<=-M_PI ) a3 += 2.0*M_PI;
- return a3;
- }
- /* VectorXY_distance_squared */
- inline extern double VectorXY_distance_squared(VectorXY A, VectorXY B){
- /*
- ** Return the squared distance between two VectorXYs.
- */
- double dx = B[X_IDX] - A[X_IDX];
- double dy = B[Y_IDX] - A[Y_IDX];
- return dx*dx + dy*dy;
- }
- /* VectorXY_distance */
- inline extern double VectorXY_distance(VectorXY A, VectorXY B){
- /*
- ** Return the distance between two VectorXYs.
- */
- double dx = B[X_IDX] - A[X_IDX];
- double dy = B[Y_IDX] - A[Y_IDX];
- return sqrt(dx*dx + dy*dy);
- }
- /* odiemath_cartesian_to_spherical */
- void odiemath_cartesian_to_spherical(VECTOR A,VECTOR R){
- double S;
- /* Work with a copy in case we are writing back to the same pointer */
- double radius,theta,phi;
- radius=VectorXYZ_Magnitude(A);
- S=sqrt(A[X_IDX]*A[X_IDX]+A[Y_IDX]*A[Y_IDX]);
- if (A[X_IDX] > 0.0) {
- theta =asin(A[Y_IDX]/S);
- } else {
- theta =M_PI - asin(A[Y_IDX]/S);
- }
- phi =asin(A[Z_IDX]/R[RADIUS]);
- R[RADIUS]=radius;
- R[THETA]=theta;
- R[PHI]=phi;
- }
- /* odiemath_spherical_to_cartesian */
- void odiemath_spherical_to_cartesian(VECTOR A,VECTOR R){
- /*
- ** Make a copy of the input matrix in case we are outputing back
- ** to the same pointer
- */
- double radius,theta,phi;
- radius=A[RADIUS];
- theta=A[THETA];
- phi=A[PHI];
- R[X_IDX]=radius*cos(theta)*cos(phi);
- R[Y_IDX]=radius*sin(theta)*cos(phi);
- R[Z_IDX]=radius*sin(phi);
- }
- /* odiemath_cylindrical_to_cartesian */
- void odiemath_cylindrical_to_cartesian(VECTOR A,VECTOR R){
- /*
- ** Make a copy of the input matrix in case we are outputing back
- ** to the same pointer
- */
- double radius,theta,z;
- radius=A[RADIUS];
- theta=A[THETA];
- z=A[Z_IDX];
- R[X_IDX]=radius*cos(theta);
- R[Y_IDX]=radius*sin(theta);
- R[Z_IDX]=z;
- }
- /* odiemath_cartesian_to_cylindrical */
- void odiemath_cartesian_to_cylindrical(VECTOR A,VECTOR R){
- /*
- ** Make a copy of the input matrix in case we are outputing back
- ** to the same pointer
- */
- double x,y,z;
- x=A[X_IDX];
- y=A[Y_IDX];
- z=A[Z_IDX];
- R[RADIUS]=sqrt(x*x + y*y);
- R[THETA] =atan2(y,x);
- R[Z_IDX] =z;
- }
- /* *Matrix_To_cartesian */
- const char *Matrix_To_cartesian(MATOBJ *matrix,int form){
- if(matrix->form==form) {
- return NULL;
- }
- switch(matrix->form) {
- case MATFORM_vector_xy:
- case MATFORM_vector_xyz:
- case MATFORM_vector_xyzw:
- break;
- case MATFORM_spherical:
- {
- odiemath_spherical_to_cartesian(matrix->matrix,matrix->matrix);
- matrix->form=form;
- break;
- }
- case MATFORM_polar:
- case MATFORM_cylindrical: {
- odiemath_cylindrical_to_cartesian(matrix->matrix,matrix->matrix);
- matrix->form=form;
- break;
- }
- default: {
- if(matrix->rows==1) {
- int temp=matrix->cols;
- matrix->cols=matrix->rows;
- matrix->rows=temp;
- }
- if(matrix->cols != 1) {
- return "Cannot convert to cartesian";
- }
- }
- }
- switch(form) {
- case MATFORM_vector_xyz:
- matrix->form=form;
- matrix->rows=3;
- matrix->cols=1;
- return NULL;
- case MATFORM_vector_xy:
- matrix->form=form;
- matrix->rows=2;
- matrix->cols=1;
- return NULL;
- }
- return NULL;
- }
- /* *Matrix_To_cylindrical */
- const char *Matrix_To_cylindrical(MATOBJ *matrix,int form){
- if(matrix->form==form) {
- return NULL;
- }
- switch(matrix->form) {
- case MATFORM_polar:
- case MATFORM_cylindrical:
- case MATFORM_vector_xy:
- case MATFORM_vector_xyz:
- case MATFORM_vector_xyzw:
- break;
- default:
- if(Matrix_To_cartesian(matrix,MATFORM_cartesian)) {
- return "Cannot convert to polar";
- }
- }
- if(matrix->form==MATFORM_cartesian) {
- odiemath_cartesian_to_cylindrical(matrix->matrix,matrix->matrix);
- }
- switch(form) {
- case MATFORM_cylindrical:
- matrix->form=form;
- matrix->rows=3;
- matrix->cols=1;
- return NULL;
- case MATFORM_polar:
- matrix->form=form;
- matrix->rows=2;
- matrix->cols=1;
- return NULL;
- }
- return NULL;
- }
- /* *Matrix_To_spherical */
- const char *Matrix_To_spherical(MATOBJ *matrix,int form){
- if(matrix->form==form) {
- return NULL;
- }
- if(Matrix_To_cartesian(matrix,MATFORM_cartesian)) {
- return "Cannot convert to spherical";
- }
- if(matrix->form==MATFORM_cartesian) {
- odiemath_cartesian_to_spherical(matrix->matrix,matrix->matrix);
- }
- matrix->form=form;
- matrix->rows=3;
- matrix->cols=1;
- return NULL;
- }
- /* *VectorXYZ_To_TclObj */
- Tcl_Obj *VectorXYZ_To_TclObj(VectorXYZ R){
- MATOBJ *RESULT;
- RESULT=Odie_MatrixObj_Create(MATFORM_vector_xyz);
- RESULT->matrix[X_IDX]=R[X_IDX];
- RESULT->matrix[Y_IDX]=R[Y_IDX];
- RESULT->matrix[Z_IDX]=R[Z_IDX];
- return Matrix_To_TclObj(RESULT);
- }
- /* Odie_GetVectorXYZFromTclObj */
- int Odie_GetVectorXYZFromTclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,VectorXYZ R){
- Tcl_Obj **elemPtrs;
- int cols,i;
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&MatrixObj_setFromAnyProc) {
- /*
- ** Object is a matrix
- */
- const char *err;
- MATOBJ *value=objPtr->internalRep.otherValuePtr;
- err=Matrix_To_cartesian(value,MATFORM_vector_xyz);
- if(err) {
- Tcl_AppendResult(interp,err,NULL);
- return TCL_ERROR;
- }
- R[X_IDX]=value->matrix[X_IDX];
- R[Y_IDX]=value->matrix[Y_IDX];
- R[Z_IDX]=value->matrix[Z_IDX];
- return TCL_OK;
- }
- }
- /* Step one, Measure the matrix */
- if(Tcl_ListObjGetElements(interp, objPtr, &cols, &elemPtrs)) return TCL_ERROR;
- for(i=0;i<3;i++) {
- double temp;
- if(cols<=i) {
- R[i]=0.0;
- } else {
- if(Tcl_GetDoubleFromObj(interp, elemPtrs[i], &temp)) return TCL_ERROR;
- R[i]=temp;
- }
- }
- return TCL_OK;
- }
- /* VectorXYZ_Scale */
- static inline void VectorXYZ_Scale(VECTOR A,SCALER S){
- A[X_IDX]*=S;
- A[Y_IDX]*=S;
- A[Z_IDX]*=S;
- }
- /* VectorXYZ_Zero */
- static inline void VectorXYZ_Zero(VECTORXYZ A){
- A[X_IDX]=0.0;
- A[Y_IDX]=0.0;
- A[Z_IDX]=0.0;
- }
- /* VectorXYZ_GridAlign */
- static inline void VectorXYZ_GridAlign(VECTORXYZ A,double grid){
- double x,q,grain;
- grain=grid*0.5;
- if(grid<=0) return;
- A[X_IDX]=Vector_GridScaler(A[X_IDX],grid,grain);
- A[Y_IDX]=Vector_GridScaler(A[Y_IDX],grid,grain);
- A[Z_IDX]=Vector_GridScaler(A[Z_IDX],grid,grain);
- }
- /* VectorXYZ_Copy */
- static inline void VectorXYZ_Copy(VECTORXYZ B,VECTORXYZ A){
- B[X_IDX]=A[X_IDX];
- B[Y_IDX]=A[Y_IDX];
- B[Z_IDX]=A[Z_IDX];
- }
- /* VectorXYZ_SamePoint */
- static inline int VectorXYZ_SamePoint(VECTORXYZ A,VECTORXYZ B){
- if(A==B) {
- return 1;
- }
- if(fabs(B[X_IDX]-A[X_IDX])>Vector_Tolerance) return 0;
- if(fabs(B[Y_IDX]-A[Y_IDX])>Vector_Tolerance) return 0;
- if(fabs(B[Z_IDX]-A[Z_IDX])>Vector_Tolerance) return 0;
- return 1;
- }
- /* VectorXYZ_IsZero */
- static inline int VectorXYZ_IsZero(VECTORXYZ A){
- if(!A) return 1;
- if(fabs(A[X_IDX])>Vector_Tolerance) return 0;
- if(fabs(A[Y_IDX])>Vector_Tolerance) return 0;
- if(fabs(A[Z_IDX])>Vector_Tolerance) return 0;
- return 1;
- }
- /* VectorXYZ_Cross_Product */
- static inline void VectorXYZ_Cross_Product(VectorXYZ C,VectorXYZ A,VectorXYZ B){
- C[X_IDX] = A[Y_IDX] * B[Z_IDX] - A[Z_IDX] * B[Y_IDX];
- C[Y_IDX] = A[Z_IDX] * B[X_IDX] - A[X_IDX] * B[Z_IDX];
- C[Z_IDX] = A[X_IDX] * B[Y_IDX] - A[Y_IDX] * B[X_IDX];
- }
- /* VectorXYZ_Add */
- static inline void VectorXYZ_Add(VECTORXYZ C,VECTORXYZ A,VECTORXYZ B){
- C[X_IDX]=B[X_IDX]+A[X_IDX];
- C[Y_IDX]=B[Y_IDX]+A[Y_IDX];
- C[Z_IDX]=B[Z_IDX]+A[Z_IDX];
- }
- /* VectorXYZ_Subtract */
- static inline void VectorXYZ_Subtract(VECTORXYZ C,VECTORXYZ A,VECTORXYZ B){
- C[X_IDX]=A[X_IDX]-B[X_IDX];
- C[Y_IDX]=A[Y_IDX]-B[Y_IDX];
- C[Z_IDX]=A[Z_IDX]-B[Z_IDX];
- }
- /* VectorXYZ_IsOrthagonal */
- static inline int VectorXYZ_IsOrthagonal(VECTORXYZ A,VECTORXYZ B){
- int result=0;
- if((A[X_IDX]-B[X_IDX])>Vector_Tolerance) result++;
- if((A[Y_IDX]-B[Y_IDX])>Vector_Tolerance) result++;
- if((A[Z_IDX]-B[Z_IDX])>Vector_Tolerance) result++;
- return result>1 ? 0 : 1;
- }
- /* VectorXYZ_Midpoint */
- static inline void VectorXYZ_Midpoint(VECTORXYZ C,VECTORXYZ A,VECTORXYZ B){
- C[X_IDX]=(B[X_IDX]-A[X_IDX])*0.5+A[X_IDX];
- C[Y_IDX]=(B[Y_IDX]-A[Y_IDX])*0.5+A[Y_IDX];
- C[Z_IDX]=(B[Z_IDX]-A[Z_IDX])*0.5+A[Z_IDX];
- }
- /* VectorXYZ_Distance */
- static inline double VectorXYZ_Distance(VECTORXYZ A,VECTORXYZ B){
- double dx,dy,dz;
- dx=B[X_IDX]-A[X_IDX];
- dy=B[Y_IDX]-A[Y_IDX];
- dz=B[Z_IDX]-A[Z_IDX];
- return sqrt(dx*dx+dy*dy+dz*dz);
- }
- /* VectorXYZ_DistanceSq */
- static inline double VectorXYZ_DistanceSq(VECTORXYZ A,VECTORXYZ B){
- double dx,dy,dz;
- dx=A[X_IDX]-B[X_IDX];
- dy=A[Y_IDX]-B[Y_IDX];
- dz=A[Z_IDX]-B[Z_IDX];
- return (dx*dx+dy*dy+dz*dz);
- }
- /* VectorXYZ_Dot_Product */
- static inline double VectorXYZ_Dot_Product(VectorXYZ A,VectorXYZ B){
- double r;
- r=A[X_IDX] * B[X_IDX] + A[Y_IDX] * B[Y_IDX] + A[Z_IDX] * B[Z_IDX];
- if(fabs(r)<__FLT_EPSILON__) {
- return 0.0;
- }
- return r;
- }
- /* VectorXYZ_MatrixMultiply */
- static inline void VectorXYZ_MatrixMultiply(VECTORXYZ R,VECTORXYZ A,AFFINE M){
- double temp[4];
- temp[0]=A[X_IDX]*M[AFFINE_IDX_0_0] + A[Y_IDX]*M[AFFINE_IDX_1_0] + A[Z_IDX]* M[AFFINE_IDX_2_0] + M[AFFINE_IDX_3_0];
- temp[1]=A[X_IDX]*M[AFFINE_IDX_0_1] + A[Y_IDX]*M[AFFINE_IDX_1_1] + A[Z_IDX]* M[AFFINE_IDX_2_1] + M[AFFINE_IDX_3_1];
- temp[2]=A[X_IDX]*M[AFFINE_IDX_0_2] + A[Y_IDX]*M[AFFINE_IDX_1_2] + A[Z_IDX]* M[AFFINE_IDX_2_2] + M[AFFINE_IDX_3_2];
- R[0]=temp[0];
- R[1]=temp[1];
- R[2]=temp[2];
- }
- /* VectorXYZ_MagnitudeSq */
- static inline double VectorXYZ_MagnitudeSq(VECTOR A){
- double length=A[0]*A[0]+A[1]*A[1]+A[2]*A[2];
- if(length<Vector_Tolerance) {
- return 0.0;
- }
- return length;
- }
- /* VectorXYZ_Magnitude */
- static inline double VectorXYZ_Magnitude(VECTOR A){
- double length=sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
- if(length<Vector_Tolerance) {
- return 0.0;
- }
- return length;
- }
- /* VectorXYZ_MagnitudeInvSqr */
- static inline double VectorXYZ_MagnitudeInvSqr(VECTOR A){
- double r=A[0]+A[1]+A[2];
- if(fabs(r)<Vector_Tolerance) {
- return NAN;
- }
- return (1.0/(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]));
- }
- /* VectorXYZ_Normalize */
- static inline int VectorXYZ_Normalize(VectorXYZ A){
- double d;
- double r=VectorXYZ_Magnitude(A);
- if(fabs(r) < __FLT_EPSILON__) {
- A[0]=0.0;
- A[1]=0.0;
- A[3]=0.0;
- return 1;
- } else {
- d=1.0 / r;
- A[0]*=d;
- A[1]*=d;
- A[2]*=d;
- return 0;
- }
- }
- /* VectorXYZ_PointIsOnSegment */
- static inline int VectorXYZ_PointIsOnSegment(VectorXYZ POINT,VectorXYZ A,VectorXYZ B){
- VectorXYZ INTERSECT;
- double t;
- t=VectorXYZ_ClosestPointOnSegment(A,B,POINT,INTERSECT);
- if (t<0.0 && t>1.0) return 0;
- if(VectorXYZ_DistanceSq(POINT,INTERSECT)>Vector_Tolerance_Sq) return 0;
- return 1;
- }
- /* VectorXYZ_AxisOfNormal */
- static inline int VectorXYZ_AxisOfNormal(VectorXYZ NORMAL){
- if(fabs(NORMAL[Z_IDX])>fabs(NORMAL[X_IDX])) {
- if (fabs(NORMAL[Z_IDX])>fabs(NORMAL[Y_IDX])) {
- return Z_IDX;
- } else {
- return Y_IDX;
- }
- }
- if (fabs(NORMAL[X_IDX])>fabs(NORMAL[Y_IDX])) {
- return X_IDX;
- } else {
- return Y_IDX;
- }
- }
- /* VectorXYZ_NormalStrictAxisAligned */
- static inline int VectorXYZ_NormalStrictAxisAligned(VectorXYZ NORMAL){
- int i;
- for(i=2;i>=0;i--) {
- if(1.0-fabs(NORMAL[i]) < Vector_Tolerance) return i;
- }
- return -1;
- }
- /* VectorXYZ_AxisAligned */
- static inline int VectorXYZ_AxisAligned(VectorXYZ A,VectorXYZ B,VectorXYZ C){
- int i;
- for(i=2;i>=0;i--) {
- if(fabs((C[i]-B[i])+(B[i]-A[i])) < Vector_Tolerance) return i;
- }
- return -1;
- }
- /* VectorXYZ_BendDirection */
- static inline int VectorXYZ_BendDirection(VectorXYZ A,VectorXYZ B,VectorXYZ C){
- int axis;
- VectorXYZ D1,D2;
- if(VectorXYZ_SamePoint(A,C)) {
- return -1;
- }
- /* If all points are axis aligned. We can treat as a 2d problem */
- axis=VectorXYZ_AxisAligned(A,B,C);
- if(axis==Z_IDX) {
- double r = (A[Y_IDX]-B[Y_IDX])*(C[X_IDX]-B[X_IDX]) + (B[X_IDX]-A[X_IDX])*(C[Y_IDX]-B[Y_IDX]);
- if(fabs(r) < __FLT_EPSILON__) return 0;
- return r<0.0 ? +1 : (r>0.0 ? -1 : 0);
- }
- if(axis==Y_IDX) {
- double r = (A[X_IDX]-B[X_IDX])*(C[Z_IDX]-B[Z_IDX]) + (B[Z_IDX]-A[Z_IDX])*(C[X_IDX]-B[X_IDX]);
- if(fabs(r) < __FLT_EPSILON__) return 0;
- return r<0.0 ? +1 : (r>0.0 ? -1 : 0);
- }
- if(axis==X_IDX) {
- /* All points are axis aligned on Z. We can treat as a 2d problem */
- double r = (A[Z_IDX]-B[Z_IDX])*(C[Y_IDX]-B[Y_IDX]) + (B[Y_IDX]-A[Y_IDX])*(C[Z_IDX]-B[Z_IDX]);
- if(fabs(r) < __FLT_EPSILON__) return 0;
- return r<0.0 ? +1 : (r>0.0 ? -1 : 0);
- }
- VectorXYZ_Cross_Product(D1,B,A);
- VectorXYZ_Cross_Product(D2,C,B);
- if(VectorXYZ_IsZero(D1) && VectorXYZ_IsZero(D2)) {
- /* We must be colinear */
- double r=(A[X_IDX]-B[X_IDX])*(C[X_IDX]-B[X_IDX])+(A[Y_IDX]-B[Y_IDX])*(C[Y_IDX]-B[Y_IDX])+(A[Z_IDX]-B[Z_IDX])*(C[Z_IDX]-B[Z_IDX]);
- if(r<0) {
- return 0;
- }
- return -1;
- }
- /* Gauge the direction of the cross products. If all axis agree, we are pointed the right way */
- if(D1[X_IDX]>=0 && D2[X_IDX]<0) {
- return -1;
- }
- if(D1[Y_IDX]>=0 && D2[Y_IDX]<0) {
- return -1;
- }
- if(D1[Z_IDX]>=0 && D2[Z_IDX]<0) {
- return -1;
- }
- return 1;
- }
- /* VectorXYZ_Angle_Three_Point */
- static inline double VectorXYZ_Angle_Three_Point(VectorXYZ A,VectorXYZ B,VectorXYZ C,VectorXYZ normal){
- double dotprod,num;
- VectorXYZ D1,D2;
- int axis;
- if(VectorXYZ_SamePoint(A,C)) {
- return M_PI;
- }
- axis=VectorXYZ_AxisAligned(A,B,C);
- if(axis==Z_IDX) {
- /* All points are axis aligned on Z. We can treat as a 2d problem */
- return VectorXY_Angle_Three_Point(A,B,C);
- }
- VectorXYZ_Subtract(D1,B,A);
- VectorXYZ_Subtract(D2,C,B);
- num=VectorXYZ_Magnitude(D1)*VectorXYZ_Magnitude(D2);
- if(fabs(num)<Vector_Tolerance) {
- /* At least one of the vectors is zero magnetude
- ** Assume any angle is good */
- return 0.0;
- }
- dotprod=VectorXYZ_Dot_Product(D1,D2);
- return acos(dotprod/num);
- }
- /* VectorXYZ_IsColinear */
- static inline int VectorXYZ_IsColinear(VectorXYZ A,VectorXYZ B,VectorXYZ C){
- double c;
- if(VectorXYZ_SamePoint(A,C)) {
- return 1;
- }
- c=( C[Z_IDX] - A[Z_IDX] ) * ( B[Y_IDX] - A[Y_IDX] ) - ( B[Z_IDX] - A[Z_IDX] ) * ( C[Y_IDX] - A[Y_IDX] );
- if(fabs(c)>Vector_Tolerance) return 0;
- c=( B[Z_IDX] - A[Z_IDX] ) * ( C[X_IDX] - A[X_IDX] ) - ( B[X_IDX] - A[X_IDX] ) * ( C[Z_IDX] - A[Z_IDX] );
- if(fabs(c)>Vector_Tolerance) return 0;
- c=( B[X_IDX] - A[X_IDX] ) * ( C[Y_IDX] - A[Y_IDX] ) - ( B[Y_IDX] - A[Y_IDX] ) * ( C[X_IDX] - A[X_IDX] );
- if(fabs(c)>Vector_Tolerance) return 0;
- return 1;
- }
- /* VectorXYZ_IsCoplaner */
- static inline int VectorXYZ_IsCoplaner(VectorXYZ x1,VectorXYZ x2,VectorXYZ x3,VectorXYZ x4){
- double c;
- VectorXYZ d12,d14,d13,cross;
- VectorXYZ_Subtract(d12,x2,x1);
- VectorXYZ_Subtract(d14,x4,x1);
- VectorXYZ_Cross_Product(cross,d12,d14);
- VectorXYZ_Subtract(d13,x3,x1);
- c=VectorXYZ_Dot_Product(cross,d13);
- if(fabs(c)>Vector_Tolerance) return 0;
- return 1;
- }
- /* VectorXYZ_LineLineCoincident */
- static inline int VectorXYZ_LineLineCoincident(
- VectorXYZ A1, VectorXYZ A2, VectorXYZ B1, VectorXYZ B2,
- VectorXYZ ICEPT1, VectorXYZ ICEPT2
- ){
- int a,b,result=0;
- /*
- ** Optimization - two lines can't be coincident if they don't
- ** occupy the same region of space
- */
- if(!VectorXYZ_BBOX_Overlap_TwoVectors(A1,A2,B1,B2)) {
- return 0;
- }
- if(VectorXYZ_SamePoint(A1,B1)) {
- if(VectorXYZ_SamePoint(A2,B2)) {
- VectorXYZ_Copy(ICEPT1,A1);
- VectorXYZ_Copy(ICEPT2,A2);
- return 30;
- }
- }
- if(VectorXYZ_SamePoint(A2,B1)) {
- if(VectorXYZ_SamePoint(A1,B2)) {
- VectorXYZ_Copy(ICEPT1,A1);
- VectorXYZ_Copy(ICEPT2,A2);
- return 30;
- }
- }
- a=VectorXYZ_IsColinear(A1,B1,B2);
- b=VectorXYZ_IsColinear(A2,B1,B2);
- if(a==0 || b==0) {
- /* The two lines are not colinear */
- int c;
- double x,y;
- c=VectorXYZ_LineLineIntersect(A1,A2,B1,B2,ICEPT1,ICEPT2,&x,&y);
- if(c>0) {
- if(x<=0 || y<=0) return 0;
- if(x>=1 || y>=1) return 0;
- /* True if both intercepts happen on a single point */
- return 1;
- }
- }
- if(VectorXYZ_PointIsOnSegment(A1,B1,B2)) {
- result |= 2;
- }
- if(VectorXYZ_PointIsOnSegment(A2,B1,B2)) {
- result |= 4;
- }
- if(VectorXYZ_PointIsOnSegment(B1,A1,A2)) {
- result |= 8;
- }
- if(VectorXYZ_PointIsOnSegment(B2,A1,A2)) {
- result |= 16;
- }
- /* If the segments touch ends we don't count it as coincident */
- if(result==0 || result==10 || result== 18 || result == 12 || result== 20) {
- return 0;
- }
- if((result & 6)==6) {
- VectorXYZ_Copy(ICEPT1,A1);
- VectorXYZ_Copy(ICEPT2,A2);
- } else if((result & 24)==24) {
- /* Both B on A */
- VectorXYZ_Copy(ICEPT1,B1);
- VectorXYZ_Copy(ICEPT2,B2);
- } else {
- if(result & 2) {
- VectorXYZ_Copy(ICEPT1,A1);
- if(result&8) {
- VectorXYZ_Copy(ICEPT2,B1);
- } else if(result&16) {
- VectorXYZ_Copy(ICEPT2,B2);
- } else {
- VectorXYZ_Copy(ICEPT2,A1);
- }
- } else if(result & 4) {
- VectorXYZ_Copy(ICEPT1,A2);
- if(result&8) {
- VectorXYZ_Copy(ICEPT2,B1);
- } else if(result&16) {
- VectorXYZ_Copy(ICEPT2,B2);
- } else {
- VectorXYZ_Copy(ICEPT2,A2);
- }
- } else if(result & 8) {
- VectorXYZ_Copy(ICEPT1,B1);
- VectorXYZ_Copy(ICEPT1,B2);
- } else {
- VectorXYZ_Copy(ICEPT1,B2);
- VectorXYZ_Copy(ICEPT2,B2);
- }
- }
- return result;
- }
- /* VectorXYZ_LineLineIntersect */
- static inline int VectorXYZ_LineLineIntersect(
- VectorXYZ p1, VectorXYZ p2, VectorXYZ p3, VectorXYZ p4,
- VectorXYZ pA, VectorXYZ pB, double *mua, double *mub
- ){
- VectorXYZ p13,p43,p21;
- double d1343,d4321,d1321,d4343,d2121;
- double numer,denom;
- p13[X_IDX] = p1[X_IDX] - p3[X_IDX];
- p13[Y_IDX] = p1[Y_IDX] - p3[Y_IDX];
- p13[Z_IDX] = p1[Z_IDX] - p3[Z_IDX];
- p43[X_IDX] = p4[X_IDX] - p3[X_IDX];
- p43[Y_IDX] = p4[Y_IDX] - p3[Y_IDX];
- p43[Z_IDX] = p4[Z_IDX] - p3[Z_IDX];
- if (fabs(p43[X_IDX]) < Vector_Tolerance && fabs(p43[Y_IDX]) < Vector_Tolerance && fabs(p43[Z_IDX]) < Vector_Tolerance)
- return(0);
- p21[X_IDX] = p2[X_IDX] - p1[X_IDX];
- p21[Y_IDX] = p2[Y_IDX] - p1[Y_IDX];
- p21[Z_IDX] = p2[Z_IDX] - p1[Z_IDX];
- if (fabs(p21[X_IDX]) < Vector_Tolerance && fabs(p21[Y_IDX]) < Vector_Tolerance && fabs(p21[Z_IDX]) < Vector_Tolerance)
- return(0);
- d1343 = p13[X_IDX] * p43[X_IDX] + p13[Y_IDX] * p43[Y_IDX] + p13[Z_IDX] * p43[Z_IDX];
- d4321 = p43[X_IDX] * p21[X_IDX] + p43[Y_IDX] * p21[Y_IDX] + p43[Z_IDX] * p21[Z_IDX];
- d1321 = p13[X_IDX] * p21[X_IDX] + p13[Y_IDX] * p21[Y_IDX] + p13[Z_IDX] * p21[Z_IDX];
- d4343 = p43[X_IDX] * p43[X_IDX] + p43[Y_IDX] * p43[Y_IDX] + p43[Z_IDX] * p43[Z_IDX];
- d2121 = p21[X_IDX] * p21[X_IDX] + p21[Y_IDX] * p21[Y_IDX] + p21[Z_IDX] * p21[Z_IDX];
- denom = d2121 * d4343 - d4321 * d4321;
- if (fabs(denom) < __FLT_EPSILON__)
- return(0);
- numer = d1343 * d4321 - d1321 * d4343;
- *mua = numer / denom;
- *mub = (d1343 + d4321 * (*mua)) / d4343;
- pA[X_IDX] = p1[X_IDX] + *mua * p21[X_IDX];
- pA[Y_IDX] = p1[Y_IDX] + *mua * p21[Y_IDX];
- pA[Z_IDX] = p1[Z_IDX] + *mua * p21[Z_IDX];
- pB[X_IDX] = p3[X_IDX] + *mub * p43[X_IDX];
- pB[Y_IDX] = p3[Y_IDX] + *mub * p43[Y_IDX];
- pB[Z_IDX] = p3[Z_IDX] + *mub * p43[Z_IDX];
- return(1);
- }
- /* VectorXYZ_ClosestPointOnSegment */
- static double VectorXYZ_ClosestPointOnSegment (
- VectorXYZ A, VectorXYZ B, /* End points of the line segment */
- VectorXYZ X, /* The point outside the line */
- VectorXYZ R /* Write closest point on line segment here */
- ){
- VectorXYZ v1, v2;
- double t, s,mag;
- VectorXYZ_Subtract(v1, X, A);
- VectorXYZ_Subtract(v2, B, A);
- mag=VectorXYZ_MagnitudeSq(v2);
- if(mag<Vector_Tolerance_Sq) {
- /* A, B and X are on the same point */
- R[X_IDX] = A[X_IDX];
- R[Y_IDX] = A[Y_IDX];
- R[Z_IDX] = A[Z_IDX];
- return 0.5;
- }
- t = VectorXYZ_Dot_Product(v1, v2)/VectorXYZ_MagnitudeSq(v2);
- if( t<0.0 ){
- VectorXYZ_Copy(R,A);
- } else if( t>1.0 ){
- VectorXYZ_Copy(R,B);
- } else {
- s = 1.0 - t;
- R[X_IDX] = A[X_IDX]*s + B[X_IDX]*t;
- R[Y_IDX] = A[Y_IDX]*s + B[Y_IDX]*t;
- R[Z_IDX] = A[Z_IDX]*s + B[Z_IDX]*t;
- }
- return t;
- }
- /* VectorXYX_solve3by3 */
- static int VectorXYX_solve3by3(double *m){
- int i, j, k;
- double x, y, scale;
- /* Process three rows from top to bottom */
- for(i=0; i<3; i++){
- /* Find the pivot for the i-th row */
- x = fabs(m[i*5]);
- k = i;
- for(j=i+1; j<3; j++){
- y = fabs(m[j*4+i]);
- if( y>x ){
- x = y;
- k = j;
- }
- }
- /* Swap in the pivot */
- if( k>i ){
- double t;
- int n, p, q;
- p = i*5;
- q = k*4+i;
- for(n=i; n<4; n++, p++, q++){
- t = m[p];
- m[p] = m[q];
- m[q] = t;
- }
- }
- /* No solution if the pivot is 0.0 */
- if( m[i*5]==0.0 ) {
- return 1;
- }
- /* Divide the i-th row by the pivot */
- scale = m[i*5];
- for(j=i; j<4; j++){
- m[i*4+j] /= scale;
- }
- /* Add the i-th row to other rows to eliminate the i-th term. */
- for(j=i+1; j<3; j++){
- double scale = -m[j*4+i];
- for(k=i; k<4; k++){
- m[j*4+k] += m[i*4+k]*scale;
- }
- }
- }
- /* Now we have an upper triangular matrix with a diagonal of 1.
- ** Finishing the solution is easy */
- for(i=1; i>=0; i--){
- for(j=2; j>i; j--){
- m[i*4+3] -= m[j*4+3]*m[i*4+j];
- }
- }
- return 0;
- }
- /* VectorXYZ_TriangleLineIntersect */
- static double VectorXYZ_TriangleLineIntersect(
- VectorXYZ A, VectorXYZ B, VectorXYZ C, /* The triangle we are trying to intersect */
- VectorXYZ pStart, /* Start of the line segment */
- VectorXYZ pEnd, /* End of the line segment */
- VectorXYZ pIntersect /* Point of intersection written here if not NULL */
- ){
- double s, t;
- double m[12];
- m[0] = pStart[X_IDX] - pEnd[X_IDX];
- m[1] = B[X_IDX] - A[X_IDX];
- m[2] = C[X_IDX] - A[X_IDX];
- m[3] = pStart[X_IDX] - A[X_IDX];
- m[4] = pStart[Y_IDX] - pEnd[Y_IDX];
- m[5] = B[Y_IDX] - A[Y_IDX];
- m[6] = C[Y_IDX] - A[Y_IDX];
- m[7] = pStart[Y_IDX] - A[Y_IDX];
- m[8] = pStart[Z_IDX] - pEnd[Z_IDX];
- m[9] = B[Z_IDX] - A[Z_IDX];
- m[10] = C[Z_IDX] - A[Z_IDX];
- m[11] = pStart[Z_IDX] - A[Z_IDX];
- if( VectorXYX_solve3by3(m) ){
- /* The line is parallel or coplanar with the triangle */
- return -1.0;
- }
- t = m[3];
- if( t<0.0 || t>1.0 ){
- /* The point of intersection is off the ends of the line segment */
- return -1.0;
- }
- if( m[7]<0.0 || m[7]>1.0 || m[11]<0.0 || m[11]>1.0 || (m[7]+m[11])>1.0 ){
- /* The point of intersection is outside of the triangle boundary */
- return -1.0;
- }
- s = 1.0 - t;
- pIntersect[X_IDX] = pStart[X_IDX]*s + pEnd[X_IDX]*t;
- pIntersect[Y_IDX] = pStart[Y_IDX]*s + pEnd[Y_IDX]*t;
- pIntersect[Z_IDX] = pStart[Z_IDX]*s + pEnd[Z_IDX]*t;
- return t;
- }
- /* VectorXYZ_Normal_of_Three_Points */
- static inline void VectorXYZ_Normal_of_Three_Points(VectorXYZ normal,VectorXYZ A,VectorXYZ B,VectorXYZ C){
- VectorXYZ one,two;
- VectorXYZ_Subtract(one, B, A);
- VectorXYZ_Subtract(two, C, A);
- normal[X_IDX] = one[Y_IDX]*two[Z_IDX] - one[Z_IDX]*two[Y_IDX];
- normal[Y_IDX] = one[Z_IDX]*two[X_IDX] - one[X_IDX]*two[Z_IDX];
- normal[Z_IDX] = one[X_IDX]*two[Y_IDX] - one[Y_IDX]*two[X_IDX];
- }
- /* VectorXYZ_LineSphereIntersect */
- int VectorXYZ_LineSphereIntersect(
- double p1_x, double p1_y, double p1_z,
- double p2_x, double p2_y, double p2_z,
- double sc_x, double sc_y, double sc_z,
- double r,
- double *mu1, double *mu2){
- /*
- ** Detect the intersection of a line and a sphere
- ** Adapted from: http://http://paulbourke.net/geometry/circlesphere/raysphere.c
- */
- double a,b,c;
- double bb4ac;
- double dp_x,dp_y,dp_z;
- *mu1 = 0;
- *mu2 = 0;
- dp_x = p2_x - p1_x;
- dp_y = p2_y - p1_y;
- dp_z = p2_z - p1_z;
- a = dp_x * dp_x + dp_y * dp_y + dp_z * dp_z;
- b = 2 * (dp_x * (p1_x - sc_x) + dp_y * (p1_y - sc_y) + dp_z * (p1_z - sc_z));
- c = sc_x * sc_x + sc_y * sc_y + sc_z * sc_z;
- c += p1_x * p1_x + p1_y * p1_y + p1_z * p1_z;
- c -= 2 * (sc_x * p1_x + sc_y * p1_y + sc_z * p1_z);
- c -= r * r;
- bb4ac = b * b - 4 * a * c;
- if (ODIE_Real_Is_Zero(a) || bb4ac < 0) {
- return(0);
- }
- *mu1 = (-b + sqrt(bb4ac)) / (2 * a);
- *mu2 = (-b - sqrt(bb4ac)) / (2 * a);
- return(1);
- }
- /* *VectorXYZ_ToString */
- char *VectorXYZ_ToString(VectorXYZ VECTOR){
- char *out=Tcl_Alloc(128);
- sprintf(out,"<%g %g %g>",(float)VECTOR[X_IDX],(float)VECTOR[Y_IDX],(float)VECTOR[Z_IDX]);
- return out;
- }
- /* Vector_Set_Tolerance */
- void Vector_Set_Tolerance(double newvalue){
- Vector_Tolerance=newvalue;
- Vector_Tolerance_Sq=newvalue*newvalue;
- }
- /* *Vector_Alloc */
- double *Vector_Alloc(size_t size){
- double *ptr;
- if(size<128) {
- size=128;
- }
- ptr=(double*)ckalloc(size);
- memset(ptr,0,size);
- return ptr;
- }
- /* Odie_Matrix_AABBXYZ_From_TclObj */
- STUB_EXPORT int Odie_Matrix_AABBXYZ_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,AABBXYZ ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_aabb_xyz,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(AABBXYZ));
- return TCL_OK;
- }
- /* *Odie_Matrix_AABBXYZ_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_AABBXYZ_To_TclObj(AABBXYZ ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_aabb_xyz);
- memcpy(C->matrix,ptr,sizeof(AABBXYZ));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_Matrix_AFFINE_From_TclObj */
- STUB_EXPORT int Odie_Matrix_AFFINE_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,AFFINE ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_affine,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(AFFINE));
- return TCL_OK;
- }
- /* *Odie_Matrix_AFFINE_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_AFFINE_To_TclObj(AFFINE ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- memcpy(C->matrix,ptr,sizeof(AFFINE));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_Matrix_BBOXXY_From_TclObj */
- STUB_EXPORT int Odie_Matrix_BBOXXY_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,BBOXXY ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_bbox_xy,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(BBOXXY));
- return TCL_OK;
- }
- /* *Odie_Matrix_BBOXXY_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_BBOXXY_To_TclObj(BBOXXY ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_bbox_xy);
- memcpy(C->matrix,ptr,sizeof(BBOXXY));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_Matrix_AFFINE3X3_From_TclObj */
- STUB_EXPORT int Odie_Matrix_AFFINE3X3_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,AFFINE3X3 ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_mat3,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(AFFINE3X3));
- return TCL_OK;
- }
- /* *Odie_Matrix_AFFINE3X3_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_AFFINE3X3_To_TclObj(AFFINE3X3 ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_mat3);
- memcpy(C->matrix,ptr,sizeof(AFFINE3X3));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_Matrix_QUATERNION_From_TclObj */
- STUB_EXPORT int Odie_Matrix_QUATERNION_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,QUATERNION ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_quaternion,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(QUATERNION));
- return TCL_OK;
- }
- /* *Odie_Matrix_QUATERNION_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_QUATERNION_To_TclObj(QUATERNION ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_quaternion);
- memcpy(C->matrix,ptr,sizeof(QUATERNION));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_Matrix_VECTORXY_From_TclObj */
- STUB_EXPORT int Odie_Matrix_VECTORXY_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,VECTORXY ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_vector_xy,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(VECTORXY));
- return TCL_OK;
- }
- /* *Odie_Matrix_VECTORXY_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_VECTORXY_To_TclObj(VECTORXY ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_vector_xy);
- memcpy(C->matrix,ptr,sizeof(VECTORXY));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_Matrix_VectorXYZ_From_TclObj */
- STUB_EXPORT int Odie_Matrix_VectorXYZ_From_TclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,VectorXYZ ptr){
- Odie_MatrixObj *T;
- if(Odie_GetMatrixFromTclObj(interp,objPtr,MATFORM_vector_xyz,&T)) return TCL_ERROR;
- memcpy(ptr,T->matrix,sizeof(VectorXYZ));
- return TCL_OK;
- }
- /* *Odie_Matrix_VectorXYZ_To_TclObj */
- STUB_EXPORT Tcl_Obj *Odie_Matrix_VectorXYZ_To_TclObj(VectorXYZ ptr){
- Odie_MatrixObj *C;
- Tcl_Obj *result;
- C=Odie_MatrixObj_Create(MATFORM_vector_xyz);
- memcpy(C->matrix,ptr,sizeof(VectorXYZ));
- result=Matrix_To_TclObj(C);
- return result;
- }
- /* Odie_GetIntFromObj */
- int Odie_GetIntFromObj(Tcl_Interp *interp,Tcl_Obj *tclObj,int *result){
- if(!Tcl_GetIntFromObj(NULL,tclObj,result)) {
- return TCL_OK;
- }
- double s;
- if(Tcl_GetDoubleFromObj(interp,tclObj,&s)) return TCL_ERROR;
- *result=(int)round(s);
- return TCL_OK;
- }
- /* Odie_GetMatrixFromTclObj */
- int Odie_GetMatrixFromTclObj(Tcl_Interp *interp,Tcl_Obj *tclObj,int form,Odie_MatrixObj **result){
- const char *(*xConvertToForm)(MATOBJ*,int)=MatrixForms[form].xConvertToForm;
- const char *error;
- *result=NULL;
- if(MatrixObj_setFromAnyProc(interp,tclObj)) {
- return TCL_ERROR;
- }
- *result=tclObj->internalRep.otherValuePtr;
- if(!xConvertToForm) {
- return TCL_OK;
- }
- error=xConvertToForm(*result,form);
- if(error) {
- Tcl_SetObjResult(interp,Tcl_NewStringObj(error,-1));
- return TCL_ERROR;
- }
- return TCL_OK;
- }
- /* *Odie_Matrix_Duplicate */
- Odie_MatrixObj *Odie_Matrix_Duplicate(Odie_MatrixObj *src){
- Odie_MatrixObj *dest;
- size_t matsize,size;
- matsize=sizeof(double)*src->rows*src->cols;
- if(matsize<128) {
- matsize=128;
- }
- size=matsize+sizeof(Odie_MatrixObj);
- dest=(Odie_MatrixObj *)Odie_Alloc(size);
- memcpy(dest,src,size);
- return dest;
- }
- /* *Odie_MatrixObj_Create_NXN */
- Odie_MatrixObj *Odie_MatrixObj_Create_NXN(int rows,int cols){
- Odie_MatrixObj *new;
- void *p;
- int size_t;
- size_t=rows*cols*sizeof(double);
- if(size_t<128) {
- size_t=128;
- }
- p=Odie_Alloc(sizeof(Odie_MatrixObj)+size_t);
- new=p;
- new->form=MATFORM_null;
- new->cols=cols;
- new->rows=rows;
- return new;
- }
- /* *Odie_MatrixObj_Create */
- Odie_MatrixObj *Odie_MatrixObj_Create(int form){
- Odie_MatrixObj *new;
- int rows,cols;
- void *p;
- int size_t;
- rows=MatrixForms[form].rows;
- cols=MatrixForms[form].cols;
- size_t=rows*cols*sizeof(double);
- if(size_t<128) {
- size_t=128;
- }
- p=Odie_Alloc(sizeof(Odie_MatrixObj)+size_t);
- new=p;
- new->form=form;
- new->cols=cols;
- new->rows=rows;
- return new;
- }
- /* Matrix_Free */
- void Matrix_Free(Odie_MatrixObj *matrix){
- if(!matrix) return;
- matrix->refCount--;
- /*
- ** Seems counter intuitive, but freeing when refCount==0 causes
- ** Tcl to Crash
- */
- if(matrix->refCount<0) {
- Odie_Free(matrix);
- }
- }
- /* *Matrix_ToAny */
- const char *Matrix_ToAny(Odie_MatrixObj *matrix,int form){
- /* Accept any input */
- matrix->form=form;
- return NULL;
- }
- /* Odie_TclObj_To_MatrixObj */
- int Odie_TclObj_To_MatrixObj(Tcl_Interp *interp,Tcl_Obj *listPtr,Odie_MatrixObj **matrix){
- Odie_MatrixObj *pNew;
- Tcl_Obj **rowPtrs;
- Tcl_Obj **elemPtrs;
- int result;
- int rows,cols;
- int idx,i,j;
- int len;
- /* Step one, Measure the matrix */
- result = Tcl_ListObjGetElements(interp, listPtr, &rows, &rowPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if(rows<1) {
- Tcl_AppendResult(interp, "Could not interpret matrix", 0);
- return TCL_ERROR;
- }
- result = Tcl_ListObjGetElements(interp, rowPtrs[0], &cols, &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- /*
- ** For NULL form, we pass the rows and cols
- ** via the data structure
- */
- pNew=Odie_MatrixObj_Create_NXN(rows,cols);
- idx=-1;
- for(i=0;i<rows;i++) {
- result = Tcl_ListObjGetElements(interp, rowPtrs[i], &len, &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if(len != cols) {
- Tcl_SetObjResult(interp,Tcl_NewStringObj("Columns are not uniform",-1));
- Matrix_Free(pNew);
- return TCL_ERROR;
- }
- for(j=0;j<len;j++) {
- double temp;
- idx++;
- result = Tcl_GetDoubleFromObj(interp, elemPtrs[j], &temp);
- if (result != TCL_OK) {
- return result;
- }
- *(pNew->matrix+idx)=(SCALER)temp;
- }
- }
- *matrix=pNew;
- return TCL_OK;
- }
- /* *Matrix_To_TclObj */
- Tcl_Obj *Matrix_To_TclObj(Odie_MatrixObj *matrix){
- Tcl_Obj *dest=Tcl_NewObj();
- dest->typePtr=&matrix_tclobjtype;
- dest->internalRep.otherValuePtr=matrix;
- matrix->refCount++;
- Tcl_InvalidateStringRep(dest);
- return dest;
- }
- /* MatrixObj_setFromAnyProc */
- int MatrixObj_setFromAnyProc(Tcl_Interp *interp,Tcl_Obj *objPtr){
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&MatrixObj_setFromAnyProc) {
- /*
- ** Object is already of the type requested
- */
- return TCL_OK;
- }
- }
- Odie_MatrixObj *matrix;
- if(Odie_TclObj_To_MatrixObj(interp,objPtr,&matrix)) {
- return TCL_ERROR;
- }
- objPtr->internalRep.otherValuePtr=matrix;
- objPtr->typePtr=&matrix_tclobjtype;
- return TCL_OK;
- }
- /* MatrixObj_updateStringProc */
- void MatrixObj_updateStringProc(Tcl_Obj *objPtr){
- float value;
- char outbuffer[128];
- Tcl_DString result;
- Odie_MatrixObj *matrix=objPtr->internalRep.otherValuePtr;
- int rows,cols;
- register int j;
- /* Step 1, dimension matrix */
- rows = matrix->rows;
- cols = matrix->cols;
- Tcl_DStringInit(&result);
- if(cols==1) {
- /*
- * Output single-row matrices (i.e. vectors)
- * as a single tcl list (rather than nest them
- * as a list within a list)
- */
- for(j=0;j<rows;j++) {
- value=(float)*(matrix->matrix+j);
- //Tcl_PrintDouble(NULL,value,outbuffer);
- sprintf(outbuffer,"%g",value);
- Tcl_DStringAppendElement(&result,outbuffer);
- }
- } else if(rows==1) {
- /*
- * Output single-row matrices (i.e. vectors)
- * as a single tcl list (rather than nest them
- * as a list within a list)
- */
- for(j=0;j<cols;j++) {
- value=(float)*(matrix->matrix+j);
- //Tcl_PrintDouble(NULL,value,outbuffer);
- sprintf(outbuffer,"%g",value);
- Tcl_DStringAppendElement(&result,outbuffer);
- }
- } else {
- register int i,idx=0;
- for(i=0;i<rows;i++) {
- Tcl_DStringStartSublist(&result);
- for(j=0;j<cols;j++) {
- idx=(i*cols)+j;
- value=(float)*(matrix->matrix+idx);
- sprintf(outbuffer,"%g",value);
- Tcl_DStringAppendElement(&result,outbuffer);
- }
- Tcl_DStringEndSublist(&result);
- }
- }
- objPtr->length=Tcl_DStringLength(&result);
- objPtr->bytes=Odie_Alloc(objPtr->length+1);
- memcpy(objPtr->bytes,Tcl_DStringValue(&result),objPtr->length);
- objPtr->bytes[objPtr->length]='\0';
- Tcl_DStringFree(&result);
- }
- /* MatrixObj_dupIntRepProc */
- void MatrixObj_dupIntRepProc(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr){
- Odie_MatrixObj *srcmatrix=srcPtr->internalRep.otherValuePtr;
- Odie_MatrixObj *dupmatrix=Odie_Matrix_Duplicate(srcmatrix);
- dupPtr->typePtr=srcPtr->typePtr;
- dupPtr->internalRep.otherValuePtr=dupmatrix;
- Tcl_InvalidateStringRep(dupPtr);
- }
- /* MatrixObj_freeIntRepProc */
- void MatrixObj_freeIntRepProc(Tcl_Obj *objPtr){
- if(!objPtr->internalRep.otherValuePtr) return;
- Odie_MatrixObj *matrix=objPtr->internalRep.otherValuePtr;
- Matrix_Free(matrix);
- objPtr->typePtr=NULL;
- objPtr->internalRep.otherValuePtr=NULL;
- }
- /* MatrixObjType_Init */
- int MatrixObjType_Init(Tcl_Interp *interp){
- Tcl_RegisterObjType(&matrix_tclobjtype);
- return TCL_OK;
- }
- /* ODIE_Real_Is_Zero */
- inline extern int ODIE_Real_Is_Zero(double x){
- if(fabs(x) < __FLT_EPSILON__) {
- return 1;
- }
- return 0;
- }
- /* ODIE_Fuzzy_Compare_TclObj */
- int ODIE_Fuzzy_Compare_TclObj(Tcl_Obj *avalue,Tcl_Obj *bvalue,double epsilon){
- int result;
- char *a,*b;
- double ax,bx;
- int ai,bi;
- int atype,btype,stringcmp=0;
- ClientData internalPtrA,internalPtrB;
- if(Tcl_GetIntFromObj(NULL,avalue,&ai)) goto doublecmp;
- if(Tcl_GetIntFromObj(NULL,bvalue,&bi)) goto doublecmp;
- if(ai==bi) {
- return 0;
- } else {
- result=ai>bi ? 1 : -1;
- }
- doublecmp:
- if(Tcl_GetDoubleFromObj(NULL,avalue,&ax)) goto stringcmp;
- if(Tcl_GetDoubleFromObj(NULL,bvalue,&bx)) goto stringcmp;
- result=ODIE_Fuzzy_Compare(ax,bx,epsilon);
- return result;
- stringcmp:
- a=Tcl_GetString(avalue);
- b=Tcl_GetString(bvalue);
- return strcmp(a,b);
- }
- /* ODIE_FuzzyNumber */
- double ODIE_FuzzyNumber(double ax){
- char newstring[128];
- int expa;
- double siga,ipart,fpart,result;
- if (Odie_IsNaN(ax)) {
- return ax;
- }
- if(Odie_IsInfinite(ax)) {
- return ax;
- }
- if(ODIE_Real_Is_Zero(ax)) {
- return 0;
- }
- siga=frexp(ax,&expa);
- fpart=modf(ldexp(siga,10),&ipart);
- return ldexp(ipart,expa-10);
- }
- /* *ODIE_NewFuzzyObj */
- Tcl_Obj *ODIE_NewFuzzyObj(float ax){
- double bx;
- const char *use_format="%g";
- char newstring[128];
- if (Odie_IsNaN(ax)) {
- return Tcl_NewDoubleObj(ax);
- }
- if(Odie_IsInfinite(ax)) {
- return Tcl_NewDoubleObj(ax);
- }
- if(ODIE_Real_Is_Zero(ax)) {
- return ODIE_REAL_ZERO();
- }
- bx=fabs(ax);
- if(bx>1000000.0) {
- use_format="%g";
- } else if(bx>1000.0) {
- use_format="%.0f";
- } else if(bx>10.0) {
- use_format="%.1f";
- } else if (bx>1.0) {
- use_format="%.2f";
- } else if (bx>0.1) {
- use_format="%.3f";
- } else if (bx>0.01) {
- use_format="%.4f";
- } else if (bx>0.001) {
- use_format="%.5f";
- } else if (bx>0.0001) {
- use_format="%.6f";
- } else {
- use_format="%g";
- }
- sprintf(newstring,use_format,ax);
- return Tcl_NewStringObj(newstring,-1);
- }
- /* ODIE_Fuzzy_Compare */
- inline extern int ODIE_Fuzzy_Compare(double avalue,double bvalue,double epsilon){
- /* Handle the simple cases */
- int expa,expb;
- double siga,sigb;
- double c;
- siga=frexp(avalue,&expa);
- sigb=frexp(bvalue,&expb);
- if(expa==expb) {
- c=bvalue-avalue;
- if(fabs(c)<epsilon) {
- return 0;
- }
- }
- if(avalue>bvalue) return 1;
- return -1;
- }
- /* ODIE_Fuzzy_GTE */
- inline extern int ODIE_Fuzzy_GTE(double avalue,double bvalue){
- /* Handle the simple cases */
- if (avalue==bvalue) return 1;
- if (avalue<=ODIE_REAL_TOLERANCE && bvalue>ODIE_REAL_TOLERANCE) return 0;
- if (avalue>bvalue) return 1;
- /* Add epsilon to the send */
- avalue+=ODIE_REAL_TOLERANCE;
- if (avalue>=bvalue) return 2;
- /* For large quantities, loose the decimal points
- if(avalue>100.0 && bvalue>100.0) {
- avalue=ceil(avalue);
- bvalue=floor(bvalue);
- if (avalue>=bvalue) return 2;
- }
- */
- return 0;
- }
- /*
- ** This file implements code for braking up compartment floorplans
- ** into triangles.
- **
- ** A floorplan is defined by vectors (x0,y0,x1,y1) which define the
- ** parameter of each compartment. The interior of the compartment
- ** is always to the right of the vector. Thus the outer boundary
- ** of the compartment rotates clockwise when viewed from above.
- ** Compartments may contain holes which are interior voids surrounded
- ** by counter-clockwise rotating boundaries.
- */
- /*
- ** Compute a hash on a point.
- */
- static int hashTriagPoint(TriagPoint *p){
- int iTX = p->x/OdieGrain;
- int iTY = p->y/OdieGrain;
- return hashInt(iTX+iTY);
- }
- /*
- ** Return TRUE if A is the same point as B.
- */
- static int sameTriagPoint(TriagPoint *A, TriagPoint *B){
- return floatCompare(A->x,B->x)==0 && floatCompare(A->y,B->y)==0;
- }
- #if 0
- /*
- ** Print all vectors in the TriagSegSet. Used for debugging purposes only.
- */
- static void SegPrint(TriagSegment *p, const char *zText){
- printf("%s ", zText);
- if( p ){
- printf("%g,%g -> %g,%g\n", p->from.x, p->from.y, p->to.x, p->to.y);
- }else{
- printf(" (null)\n");
- }
- }
- static void TriagSegSetPrint(TriagSegSet *pSet){
- Link *pLink;
- printf("%d vectors:\n", pSet->nSeg);
- for(pLink=pSet->pAll; pLink; pLink=pLink->pNext){
- SegPrint(pLink->pLinkNode, " ");
- }
- }
- #endif
- /*
- ** Add a new segment to the set
- */
- static TriagSegment *TriagSegSetInsert(
- TriagSegSet *pSet,
- double x0,
- double y0,
- double x1,
- double y1,
- u8 isBoundary
- ){
- int h;
- if(pSet==NULL) {
- return NULL;
- }
- TriagSegment *p = (TriagSegment *)Odie_Alloc( sizeof(*p) );
- memset(p,0,sizeof(*p));
- x0=round(x0);
- y0=round(y0);
- x1=round(x1);
- y1=round(y1);
- if( p==0 ) {
- return NULL;
- }
- p->from.x = x0;
- p->from.y = y0;
- p->to.x = x1;
- p->to.y = y1;
- if( sameTriagPoint(&p->from, &p->to) ){
- Odie_Free((char *)p);
- return NULL;
- }
- p->isBoundary = isBoundary;
- p->notOblique = 0;
- LinkInit(p->all, p);
- LinkInit(p->tmp, p);
- LinkInit(p->orig, p);
- LinkInsert(&pSet->pAll, &p->all);
- h = hashTriagPoint(&p->from);
- LinkInsert(&pSet->aHash[h], &p->orig);
- pSet->nSeg++;
- pSet->pCurrent = p;
- return p;
- }
- /*
- ** Remove a segment from the segment set
- */
- static void TriagSegSetRemove(TriagSegSet *pSet, TriagSegment *p){
- LinkRemove(&p->all);
- LinkRemove(&p->orig);
- pSet->nSeg--;
- if( pSet->pCurrent==p ){
- pSet->pCurrent = pSet->pAll ? pSet->pAll->pLinkNode : 0;
- }
- }
- /*
- ** Call this routine to relink into a segment when the
- ** Seg.from vector changes.
- */
- static void TriagSegRelink(TriagSegSet *pSet, TriagSegment *p){
- int h;
- LinkRemove(&p->orig);
- h = hashTriagPoint(&p->from);
- LinkInsert(&pSet->aHash[h], &p->orig);
- }
- /*
- ** Remove all segments from a segment set
- */
- static void TriagSegSetClear(TriagSegSet *pSet){
- while( pSet->pAll ){
- TriagSegment *p;
- assert( pSet->nSeg>0 );
- p=pSet->pAll->pLinkNode;
- TriagSegSetRemove(pSet, p);
- Odie_Free((char *)p);
- }
- assert( pSet->nSeg==0 );
- }
- #if 0
- /*
- ** Advance the pSet->pAll pointer so that it is pointing to a different
- ** segment.
- */
- static void TriagSegSetStep(TriagSegSet *pSet){
- if( pSet->pCurrent ){
- Link *pNext = pSet->pCurrent->all.pNext;
- pSet->pCurrent = pNext ? pNext->pSeg : 0;
- }
- if( pSet->pCurrent==0 ){
- pSet->pCurrent = pSet->pAll ? pSet->pAll->pSeg : 0;
- }
- }
- #endif
- static inline double Dot_Product(TriagPoint *A, TriagPoint *B, TriagPoint *P){
- double r = (A->y-B->y)*(P->x-B->x) + (B->x-A->x)*(P->y-B->y);
- if(fabs(r) < IRM_EPSILON ) {
- return 0.0;
- }
- return r;
- }
- /*
- ** Consider traveling from point A to B to P. If you have to make
- ** a left-turn at B, then this routine returns -1. If P is on the
- ** same line as A and B then return 0. If you make a right turn
- ** at B in order to reach P then return +1.
- */
- static inline int rightOf(TriagPoint *A, TriagPoint *B, TriagPoint *P){
- /* Algorithm: Rotate AB 90 degrees counter-clockwise. Take
- ** the dot product with BP. The dot produce will be the product
- ** of two (non-negative) magnitudes and the cosine of the angle. So if
- ** the dot product is positive, the bend is to the left, or to the right if
- ** the dot product is negative.
- */
- double r = (A->y-B->y)*(P->x-B->x) + (B->x-A->x)*(P->y-B->y);
- if(fabs(r) < IRM_EPSILON ) {
- return 0;
- }
- if(r>0.0) {
- return -1;
- }
- return 1;
- //return r<0.0 ? +1 : (r>0.0 ? -1 : 0);
- }
- /*
- ** This is a variation on rightOf(). Return 0 only if BP is a continuation
- ** of the line AB. If BP doubles back on AB then return -1.
- */
- static inline int strictlyRightOf(TriagPoint *A, TriagPoint *B, TriagPoint *P){
- int c = rightOf(A,B,P);
- if( c==0 ){
- double r = (A->x-B->x)*(P->x-B->x) + (A->y-B->y)*(P->y-B->y);
- c = r<0.0 ? +1 : -1;
- }
- return c;
- }
- /*
- ** Return TRUE if segments AB and CD intersect
- */
- static int intersect(TriagPoint *A, TriagPoint *B, TriagPoint *C, TriagPoint *D){
- return
- rightOf(A,B,C)*rightOf(A,B,D)<0 &&
- rightOf(C,D,A)*rightOf(C,D,B)<0;
- }
- /*
- ** Return the squared distance between two points.
- */
- static double dist2(TriagPoint *A, TriagPoint *B){
- double dx = B->x - A->x;
- double dy = B->y - A->y;
- return dx*dx + dy*dy;
- }
- /*
- ** Compute angle ABC measured counter-clockwise from AB. Return the
- ** result.
- **
- ** This does not need to be a true angular measure as long as it is
- ** monotonically increasing.
- */
- static double angleOf(TriagPoint *A, TriagPoint *B, TriagPoint *C){
- double a1, a2, a3;
- if( sameTriagPoint(A,C) ){
- return M_PI;
- }
- a1 = atan2(B->y - A->y, B->x - A->x);
- a2 = atan2(C->y - B->y, C->x - B->x);
- a3 = a2-a1;
- if( a3>M_PI ) a3 -= 2.0*M_PI;
- if( a3<=-M_PI ) a3 += 2.0*M_PI;
- return a3;
- }
- static inline double idealAngle(TriagPoint *A, TriagPoint *B, TriagPoint *P){
- double theta = angleOf(A,B,P);
- double d = M_PI*0.25 - theta;
- if(ODIE_Real_Is_Zero(d)) {
- return 0.0;
- }
- return d;
- }
- /*
- ** Given line segment AB, locate segment BC and return a pointer to
- ** it. If there is not BC return NULL. If there is more than one
- ** BC return the one that minimizes the angle ABC.
- */
- static TriagSegment *TriagSegSetNext(TriagSegSet *pSet, TriagSegment *pAB){
- Link *pX;
- TriagSegment *pBest = 0;
- double angle, bestAngle;
- int cnt = 0;
- int h;
- h = hashTriagPoint(&pAB->to);
- for(pX=pSet->aHash[h]; pX; pX=pX->pNext){
- TriagSegment *pSeg = pX->pLinkNode;
- if( !sameTriagPoint(&pSeg->from, &pAB->to) ) continue;
- /* if(pAB->isBoundary > 1 && pSeg->isBoundary!=0 && pSeg->isBoundary!=pAB->isBoundary) continue; */
- if( cnt==0 ){
- pBest = pSeg;
- bestAngle = angleOf(&pAB->from, &pAB->to, &pBest->to);
- }else{
- angle = angleOf(&pAB->from, &pAB->to, &pSeg->to);
- if( angle<bestAngle ){
- bestAngle = angle;
- pBest = pSeg;
- }
- }
- cnt++;
- }
- return pBest;
- }
- /*
- ** Find and return the line segment that goes from A to B. Return NULL
- ** if there is not such line segment
- */
- static TriagSegment *TriagSegSetFind(TriagSegSet *pSet, TriagPoint *A, TriagPoint *B){
- Link *pX;
- TriagSegment *p;
- int h;
- h = hashTriagPoint(A);
- for(pX=pSet->aHash[h]; pX; pX=pX->pNext){
- p = pX->pLinkNode;
- if( sameTriagPoint(&p->from, A) && sameTriagPoint(&p->to, B) ){
- return p;
- }
- }
- return 0;
- }
- /*
- ** Remove all segments whose length is less than minLength. For
- ** each segment removed, coalesce the inputs into a single new
- ** point at the center of the segment.
- */
- static void removeShortTriagSegments(TriagSegSet *pSet, double minLength){
- Link *pLoop, *pNext;
- double minLen2;
- minLen2 = minLength*minLength;
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- TriagSegment *p;
- TriagPoint from, to, center;
- p = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if( dist2(&p->from, &p->to)<minLen2 ){
- from = p->from;
- to = p->to;
- center.x = rint(0.5*(from.x + to.x));
- center.y = rint(0.5*(from.y + to.y));
- TriagSegSetRemove(pSet, p);
- Odie_Free((char *)p);
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pNext = pLoop->pNext;
- p = pLoop->pLinkNode;
- if( (p->to.x==from.x && p->to.y==from.y)
- || (p->to.x==to.x && p->to.y==to.y)
- ){
- p->to = center;
- }
- if( (p->from.x==from.x && p->from.y==from.y)
- || (p->from.x==to.x && p->from.y==to.y)
- ){
- p->from = center;
- TriagSegRelink(pSet, p);
- }
- if( p->from.x==p->to.x && p->from.y==p->to.y ){
- TriagSegSetRemove(pSet, p);
- Odie_Free((char *)p);
- }
- }
- pNext = pSet->pAll;
- }
- }
- }
- static int WalkTriagSegments(TriagSegSet *pSet) {
- Link *pLoop, *pNext;
- int changed=0;
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- TriagSegment *pAB, *pBC;
- Link *pRight, *pL2;
- int c;
- /* Find an oblique angle ABC */
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- /*
- ** If we are at an oblique for a non boundary
- ** segment, continue
- */
- if( pAB->notOblique ) continue;
- pBC = TriagSegSetNext(pSet, pAB);
- if( pBC==0 ) {
- /*
- ** Remove an orphan wall
- */
- TriagSegSetRemove(pSet, pAB);
- Odie_Free((char *)pAB);
- changed=1;
- continue;
- }
- if( (c = rightOf(&pAB->from, &pAB->to, &pBC->to))>=0 ){
- if( c>0 || !sameTriagPoint(&pAB->from, &pBC->to) ){
- pAB->notOblique = 1;
- continue;
- }
- }
- /* If we reach here, it means that ABC is an oblique angle.
- ** Locate all vertices to the right of AB.
- */
- pRight = 0;
- for(pL2=pSet->pAll; pL2; pL2=pL2->pNext){
- TriagSegment *pX = pL2->pLinkNode;
- if( strictlyRightOf(&pAB->from, &pAB->to, &pX->from)<0 ) continue;
- if( sameTriagPoint(&pAB->to, &pX->from) ) continue;
- pX->score = dist2(&pAB->to, &pX->from);
- pX->isRight = rightOf(&pBC->from, &pBC->to, &pX->from);
- LinkInit(pX->tmp, pX);
- LinkInsert(&pRight, &pX->tmp);
- }
- if( pRight==0 ){
- return TCL_ERROR;
- }
- /* pRight is a list of vertices to the right of AB. Find the
- ** closest vertex X on this list where the line BX does not intersect
- ** any other segment in the polygon. Then add segments BX and XB.
- */
- while( pRight ){
- Link *pBest=NULL;
- double bestScore;
- int bestRight;
- TriagSegment *pThis,*pX, *pQ;
- /* Search for the "best" vertex. The best vertex is the
- ** one that is closest. Though if the vertex is to the left
- ** of BC (and thus would create another oblique angle) then
- ** artificially reduce its score because we would prefer not
- ** to use it.
- */
- pBest = pRight;
- pThis=pBest->pLinkNode;
- bestScore = pThis->score;
- bestRight = pThis->isRight;
- for(pL2=pBest->pNext; pL2; pL2=pL2->pNext){
- int better=0;
- pX = pL2->pLinkNode;
- if( pX->isRight>0 && bestRight <=0 ) {
- better=1;
- } else if ( pX->isRight<=0 && bestRight>0 ) {
- better=0;
- } else if( pX->score<bestScore ){
- better=1;
- }
- if(better) {
- bestScore = pX->score;
- bestRight = pX->isRight;
- pBest = pL2;
- }
- }
- /* The best vertex is pX */
- pX = pBest->pLinkNode;
- LinkRemove(pBest);
- /* Check to see if BX intersects any segment. If it does, then
- ** go back and search for a different X
- */
- for(pL2=pSet->pAll; pL2; pL2=pL2->pNext){
- pQ = pL2->pLinkNode;
- if( pQ!=pAB && pQ!=pX
- && intersect(&pAB->to, &pX->from, &pQ->from, &pQ->to) ){
- break;
- }
- }
- if( pL2 ) continue;
- /* It did not intersect. So add BX and XB to the pSet->
- */
- TriagSegSetInsert(pSet, pAB->to.x, pAB->to.y, pX->from.x, pX->from.y, 0);
- TriagSegSetInsert(pSet, pX->from.x, pX->from.y, pAB->to.x, pAB->to.y, 0);
- pRight = 0;
- }
- changed=1;
- if(!pAB->isBoundary) {
- pNext = pSet->pAll;
- }
- }
- if(changed) {
- return TCL_CONTINUE;
- }
- return TCL_OK;
- }
- /*
- ** tclcmd: convex_subpolygons_new VECTORS ?MINLENGTH? ?HOLE? ?HOLE? ...
- **
- ** VECTORS is a list of floating-point values. Each group of four values
- ** forms a vector X0,Y0->X1,Y1. The vectors are in no particular order,
- ** but together they form one or more loops. Space to the right of each
- ** vector is within the loop and space to the left is outside.
- **
- ** Loops can be nested. The outer boundary is formed by a clockwise loop
- ** of vectors. Interior holes are formed by counter-clockwise loops.
- **
- ** The output is a list polygons. Each polygon is a list of 3 or more
- ** X,Y coordinate pairs. All polygons are convex and disjoint and they
- ** together cover the input polygon.
- **
- ** Optionally, the user can specify a series of polygons to be subtracted
- ** from the main polygon. These are given as an XY list suitable for
- ** producing a polygon on the tkcanvas
- */
- static int convexNewSubpolyCmd(
- void *pArg,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
- ){
- Tcl_Obj *pOut; /* The output list */
- Tcl_Obj *pSub; /* A sublist for a single polygon */
- int i, idx, n, nb, cnt;
- TriagSegSet set;
- double minLen = 0.0;
- if( objc!=2 && objc!=3 && objc<4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "VECTORS ?MINLENGTH? ?HOLE? ?HOLE? ...");
- return TCL_ERROR;
- }
- if( Tcl_ListObjLength(interp, objv[1], &n) ) return TCL_ERROR;
- if( objc>2 ){
- if( Tcl_GetDoubleFromObj(interp, objv[2], &minLen) ) return TCL_ERROR;
- }
- if( n<12 || n%4!=0 ){
- Tcl_AppendResult(interp, "VECTORS argument should contain at least 12 and "
- " a multiple of 4 values", 0);
- return TCL_ERROR;
- }
- memset(&set, 0, sizeof(set));
- /*
- ** Insert the polygons the user specified as
- ** the shape of the holes first
- */
- for(idx=3;idx<objc;idx++) {
- double fx,fy,px,py;
- if( Tcl_ListObjLength(interp, objv[idx], &nb) ) return TCL_ERROR;
- if( nb > 0 && (nb<6 || nb%2!=0) ){
- TriagSegSetClear(&set);
- Tcl_AppendResult(interp, "HOLES arguments should contain at least 6 and "
- " a multiple of 2 values", 0);
- return TCL_ERROR;
- }
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, objv[idx], 0, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &fx) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- Tcl_ListObjIndex(0, objv[idx], 1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &fy) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- px=fx;
- py=fy;
- for(i=2; i<nb; i+=2){
- double mx,my;
- double nx,ny;
- Tcl_ListObjIndex(0, objv[idx], i, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &nx) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- Tcl_ListObjIndex(0, objv[idx], i+1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &ny) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- /*
- TriagSegSetInsert(&set, px, py, nx, ny, idx);
- */
- mx=(nx+px)/2.0;
- my=(ny+py)/2.0;
- TriagSegSetInsert(&set, px, py, mx, my, idx);
- TriagSegSetInsert(&set, mx, my, nx, ny, idx);
- px=nx;
- py=ny;
- }
- double mx,my;
- mx=(fx+px)/2.0;
- my=(fy+py)/2.0;
- TriagSegSetInsert(&set, px, py, mx, my, idx);
- TriagSegSetInsert(&set, mx, my, fx, fy, idx);
- }
- for(i=0; i<n; i+=4){
- int j;
- double x[4];
- TriagPoint A,B,C;
- for(j=0; j<4; j++){
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, objv[1], i+j, &pObj);
- if( Odie_GetMatrixElementFromObj(interp, pObj, x, j) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- }
- A.x=x[0];
- A.y=x[1];
- C.x=x[2];
- C.y=x[3];
- B.x=(C.x+A.x)/2.0;
- B.y=(C.y+A.y)/2.0;
- /*
- ** Do not insert a vector into the wallset if it
- ** matches a vector already given. It's either redundent
- ** or the edge of a hole
- */
- if(!TriagSegSetFind(&set,&A,&C)) {
- TriagSegSetInsert(&set, A.x, A.y, B.x, B.y, 1);
- }
- if(!TriagSegSetFind(&set,&B,&C)) {
- TriagSegSetInsert(&set, B.x, B.y, C.x, C.y, 1);
- }
- }
- if( minLen>0.0 ){
- removeShortTriagSegments(&set, minLen);
- }
- cnt=0;
- i=TCL_CONTINUE;
- while(i==TCL_CONTINUE) {
- i=WalkTriagSegments(&set);
- cnt++;
- if(cnt>10) {
- break;
- }
- }
- if(i==TCL_CONTINUE) {
- Tcl_AppendResult(interp, "boundary too complex", 0);
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- if(i==TCL_ERROR) {
- Tcl_AppendResult(interp, "boundary does not enclose a finite space", 0);
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- /* Now all polygons should be convex. We just have to generate them. */
- pOut = Tcl_NewObj();
- int npoly=0;
- while( set.nSeg ){
- TriagPoint start;
- TriagSegment *pAB, *pBC;
- int valid = 0;
- int cnt = 0;
- npoly++;
- pAB = set.pAll->pLinkNode;
- start = pAB->from;
- /*
- ** Walk along the wallsets, filter out
- ** any that do not include one of the
- ** vectors given as an input of the first
- ** argument
- */
- pSub = Tcl_NewObj();
- while( pAB ){
- Tcl_ListObjAppendElement(0, pSub, Tcl_NewDoubleObj(pAB->to.x));
- Tcl_ListObjAppendElement(0, pSub, Tcl_NewDoubleObj(pAB->to.y));
- if(pAB->isBoundary < 2) valid=1;
- cnt++;
- TriagSegSetRemove(&set, pAB);
- if( sameTriagPoint(&pAB->to, &start) ) {
- break;
- }
- pBC = TriagSegSetNext(&set, pAB);
- Odie_Free((char *)pAB);
- pAB = pBC;
- }
- if( pAB==0 || cnt<3 || !valid){
- Tcl_DecrRefCount(pSub);
- }else{
- Tcl_ListObjAppendElement(0, pOut, pSub);
- }
- }
- TriagSegSetClear(&set);
- Tcl_SetObjResult(interp, pOut);
- return TCL_OK;
- }
- /*
- ** tclcmd: convex_subpolygons VECTORS ?MINLENGTH? ?HOLE? ?HOLE? ...
- **
- ** VECTORS is a list of floating-point values. Each group of four values
- ** forms a vector X0,Y0->X1,Y1. The vectors are in no particular order,
- ** but together they form one or more loops. Space to the right of each
- ** vector is within the loop and space to the left is outside.
- **
- ** Loops can be nested. The outer boundary is formed by a clockwise loop
- ** of vectors. Interior holes are formed by counter-clockwise loops.
- **
- ** The output is a list polygons. Each polygon is a list of 3 or more
- ** X,Y coordinate pairs. All polygons are convex and disjoint and they
- ** together cover the input polygon.
- **
- ** Optionally, the user can specify a series of polygons to be subtracted
- ** from the main polygon. These are given as an XY list suitable for
- ** producing a polygon on the tkcanvas
- */
- static int convexSubpolyCmd(
- void *pArg,
- Tcl_Interp *interp,
- int objc,
- Tcl_Obj *CONST objv[]
- ){
- Tcl_Obj *pOut; /* The output list */
- Tcl_Obj *pSub; /* A sublist for a single polygon */
- int i, idx, n, nb, cnt;
- TriagSegSet set;
- double minLen = 0.0;
- if( objc!=2 && objc!=3 && objc<4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "VECTORS ?MINLENGTH? ?HOLE? ?HOLE? ...");
- return TCL_ERROR;
- }
- if( Tcl_ListObjLength(interp, objv[1], &n) ) return TCL_ERROR;
- if( objc>2 ){
- if( Tcl_GetDoubleFromObj(interp, objv[2], &minLen) ) return TCL_ERROR;
- }
- if( n<12 || n%4!=0 ){
- Tcl_AppendResult(interp, "VECTORS argument should contain at least 12 and "
- " a multiple of 4 values", 0);
- return TCL_ERROR;
- }
- memset(&set, 0, sizeof(set));
- /*
- ** Insert the polygons the user specified as
- ** the shape of the holes first
- */
- for(idx=3;idx<objc;idx++) {
- double fx,fy,px,py;
- if( Tcl_ListObjLength(interp, objv[idx], &nb) ) return TCL_ERROR;
- if( nb > 0 && (nb<6 || nb%2!=0) ){
- TriagSegSetClear(&set);
- Tcl_AppendResult(interp, "HOLES arguments should contain at least 6 and "
- " a multiple of 2 values", 0);
- return TCL_ERROR;
- }
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, objv[idx], 0, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &fx) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- Tcl_ListObjIndex(0, objv[idx], 1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &fy) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- px=fx;
- py=fy;
- for(i=2; i<nb; i+=2){
- double nx,ny;
- Tcl_ListObjIndex(0, objv[idx], i, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &nx) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- Tcl_ListObjIndex(0, objv[idx], i+1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &ny) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- TriagSegSetInsert(&set, px, py, nx, ny, idx);
- px=nx;
- py=ny;
- }
- TriagSegSetInsert(&set, px, py, fx, fy, idx);
- }
- for(i=0; i<n; i+=4){
- int j;
- double x[4];
- TriagPoint A,B;
- for(j=0; j<4; j++){
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, objv[1], i+j, &pObj);
- if( Odie_GetMatrixElementFromObj(interp, pObj, x, j) ){
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- }
- A.x=x[0];
- A.y=x[1];
- B.x=x[2];
- B.y=x[3];
- /*
- ** Do not insert a vector into the wallset if it
- ** matches a vector already given. It's either redundent
- ** or the edge of a hole
- */
- if(TriagSegSetFind(&set,&A,&B)) continue;
- TriagSegSetInsert(&set, x[0], x[1], x[2], x[3], 1);
- }
- if( minLen>0.0 ){
- removeShortTriagSegments(&set, minLen);
- }
- cnt=0;
- i=TCL_CONTINUE;
- while(i==TCL_CONTINUE) {
- i=WalkTriagSegments(&set);
- cnt++;
- if(cnt>10) {
- break;
- }
- }
- if(i==TCL_CONTINUE) {
- Tcl_AppendResult(interp, "{boundary too complex}", 0);
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- if(i==TCL_ERROR) {
- Tcl_AppendResult(interp, "{boundary does not enclose a finite space}", 0);
- TriagSegSetClear(&set);
- return TCL_ERROR;
- }
- int obtuseangles=0;
- /* Now all polygons should be convex. We just have to generate them. */
- pOut = Tcl_NewObj();
- while( set.nSeg ){
- TriagPoint start;
- TriagSegment *pAB, *pBC;
- int valid = 0;
- int cnt = 0;
- pAB = set.pAll->pLinkNode;
- start = pAB->from;
- /*
- ** Walk along the wallsets, filter out
- ** any that do not include one of the
- ** vectors given as an input of the first
- ** argument
- */
- pSub = Tcl_NewObj();
- while( pAB ){
- Tcl_ListObjAppendElement(0, pSub, Tcl_NewDoubleObj(pAB->to.x));
- Tcl_ListObjAppendElement(0, pSub, Tcl_NewDoubleObj(pAB->to.y));
- pBC = TriagSegSetNext(&set, pAB);
- if(pAB->isBoundary < 2) valid=1;
- if(pAB->isRight<0) obtuseangles++;
- cnt++;
- TriagSegSetRemove(&set, pAB);
- if( sameTriagPoint(&pAB->to, &start) ) {
- break;
- }
- Odie_Free((char *)pAB);
- pAB = pBC;
- }
- if( pAB==0 || cnt<3 || !valid){
- Tcl_DecrRefCount(pSub);
- }else{
- Tcl_ListObjAppendElement(0, pOut, pSub);
- }
- }
- TriagSegSetClear(&set);
- if(obtuseangles) {
- Tcl_DecrRefCount(pOut);
- convexNewSubpolyCmd(NULL,interp,objc,objv);
- } else {
- Tcl_SetObjResult(interp, pOut);
- }
- return TCL_OK;
- }
- /*
- ** This file implements a TCL object used for tracking polygons. A
- ** single new TCL command named "poly" is defined. This command
- ** has methods for creating, deleting, and taking the intersection
- ** of 2-D polygons. There are comments on the implementation of each
- ** method to describe what the method does.
- **
- ** This module was originally developed to aid in computing the
- ** shared surface area between two compartments on separate decks.
- ** The shared surface area is needed in initializing the fire model
- ** since heat conduction between the two compartments is proportional
- ** to their shared area.
- */
- /* PolygonObj_freeIntRepProc */
- void PolygonObj_freeIntRepProc(Tcl_Obj *objPtr){
- if(objPtr->internalRep.otherValuePtr) {
- Odie_Polygon *pPoly=objPtr->internalRep.otherValuePtr;
- if(pPoly->refCount) {
- pPoly->refCount--;
- }
- if(!pPoly->refCount) {
- Tcl_Free(objPtr->internalRep.otherValuePtr);
- objPtr->internalRep.otherValuePtr=NULL;
- objPtr->typePtr=NULL;
- }
- }
- }
- /* PolygonObj_dupIntRepProc */
- void PolygonObj_dupIntRepProc(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr){
- Odie_Polygon *src=srcPtr->internalRep.otherValuePtr;
- int size=sizeof(*src)+src->nVertex*sizeof(src->v[0]);
- Odie_Polygon *copy=(Odie_Polygon *)Odie_Alloc(size);
- memcpy(copy,src,size);
- Tcl_InvalidateStringRep(dupPtr);
- dupPtr->typePtr=&polygon_tclobjtype;
- dupPtr->internalRep.otherValuePtr=copy;
- }
- /* PolygonObj_updateStringRepProc */
- void PolygonObj_updateStringRepProc(Tcl_Obj *objPtr){
- /* Update String Rep */
- char outbuffer[128];
- Tcl_DString result;
- Odie_Polygon *p=objPtr->internalRep.otherValuePtr;
- int i,j;
- Tcl_DStringInit(&result);
- j=p->nVertex-1;
- if(p->v[0][X_IDX]==p->v[j][X_IDX] && p->v[0][Y_IDX]==p->v[j][Y_IDX]) {
- j=p->nVertex-2;
- }
- for(i=0; i<=j; i++){
- sprintf(outbuffer,"%g %g",(float)p->v[i][X_IDX],(float)p->v[i][Y_IDX]);
- Tcl_DStringAppendElement(&result,outbuffer);
- }
- objPtr->length=Tcl_DStringLength(&result);
- objPtr->bytes=Odie_Alloc(objPtr->length+1);
- strcpy(objPtr->bytes,Tcl_DStringValue(&result));
- Tcl_DStringFree(&result);
- }
- /* Odie_Poly_ShimmerOrFree_TclObj */
- int Odie_Poly_ShimmerOrFree_TclObj(Tcl_Obj *objPtr,Odie_Polygon *p){
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&PolygonObj_setFromAnyProc) {
- /*
- ** Object is already of the type requested
- */
- return 1;
- }
- }
- if(Tcl_IsShared(objPtr)) {
- Odie_Free((char *)p);
- return 1;
- }
- if(objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
- Tcl_FreeInternalRepProc *freeIntRepProc=objPtr->typePtr->freeIntRepProc;
- freeIntRepProc(objPtr);
- }
- objPtr->internalRep.otherValuePtr=p;
- objPtr->typePtr=&polygon_tclobjtype;
- Tcl_IncrRefCount(objPtr);
- return 0;
- }
- /* *Odie_Poly_Create */
- Odie_Polygon *Odie_Poly_Create(int nVertex){
- Odie_Polygon *p;
- p=(Odie_Polygon *)Odie_Alloc(sizeof(*p)+(nVertex+1)*sizeof(p->v[0]));
- p->nVertex=nVertex;
- return p;
- }
- /* PolygonObj_setFromAnyProc */
- int PolygonObj_setFromAnyProc(Tcl_Interp *interp,Tcl_Obj *objPtr){
- /* Set internal rep from any Tcl_Obj */
- if(objPtr->typePtr) {
- if(objPtr->typePtr==&polygon_tclobjtype) {
- /*
- ** Object is already of the type requested
- */
- return TCL_OK;
- }
- }
- Odie_Polygon *p;
- int created=0;
- if(Odie_Polygon_GetFromTclObj(interp,objPtr,&p,&created)) {
- return TCL_ERROR;
- }
- Tcl_InvalidateStringRep(objPtr);
- objPtr->internalRep.otherValuePtr=p;
- objPtr->typePtr=&polygon_tclobjtype;
- return TCL_OK;
- }
- /* *Odie_Polygon_NewTclObj */
- Tcl_Obj *Odie_Polygon_NewTclObj(Odie_Polygon *pPoly){
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- Tcl_InvalidateStringRep(pResult);
- pPoly->refCount++;
- pResult->internalRep.otherValuePtr=pPoly;
- pResult->typePtr=&polygon_tclobjtype;
- return pResult;
- }
- /* Odie_Polygon_From_FaceXYZ */
- int Odie_Polygon_From_FaceXYZ(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_Polygon **ptr){
- int i,nVertex;
- Tcl_Obj *pElem;
- Odie_Polygon *p;
- Odie_FaceXYZ *poly;
- poly=objPtr->internalRep.otherValuePtr;
- nVertex=poly->nVertex;
- p=Odie_Poly_Create(nVertex);
- for(i=0; i<nVertex; i++){
- VectorXY_Copy(p->v[i],poly->vertex_xyz[i]);
- }
- VectorXY_Copy(p->v[nVertex],poly->vertex_xyz[0]);
- if(Odie_Polygon_ComputeArea(interp,p)) goto createfail;
- *ptr=p;
- return TCL_OK;
- createfail:
- Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Odie_Polygon_GetFromTclObj */
- int Odie_Polygon_GetFromTclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_Polygon **ptr,int *created){
- Odie_Polygon *p;
- *created=0;
- if(objPtr->typePtr) {
- if(objPtr->typePtr==&polygon_tclobjtype && objPtr->internalRep.otherValuePtr) {
- /*
- ** Object is already of the type requested
- */
- *ptr=objPtr->internalRep.otherValuePtr;
- return TCL_OK;
- }
- if(objPtr->typePtr->setFromAnyProc==&Odie_FaceXYZ_setFromAnyProc && objPtr->internalRep.otherValuePtr) {
- *created=1;
- return Odie_Polygon_From_FaceXYZ(interp,objPtr,ptr);
- }
- }
- int k,i;
- if( Tcl_ListObjLength(interp, objPtr, &k) ) return TCL_ERROR;
- if( k<6 ){
- Tcl_AppendResult(interp, "need at least 3 vertices", 0);
- return TCL_ERROR;
- }
- if( k&1 ){
- Tcl_AppendResult(interp, "coordinates should come in pairs", 0);
- return TCL_ERROR;
- }
- *created=1;
- p=(Odie_Polygon *)Odie_Alloc(sizeof(*p)+(k+2)*sizeof(p->v[0]));
- p->nVertex=k/2;
- for(i=0; i<p->nVertex; i++){
- Tcl_Obj *pElem;
- double d;
- Tcl_ListObjIndex(0, objPtr, i*2, &pElem);
- if(Tcl_GetDoubleFromObj(interp, pElem, &d)) goto createfail;
- p->v[i][X_IDX] = d;
- Tcl_ListObjIndex(0, objPtr, i*2+1, &pElem);
- if(Tcl_GetDoubleFromObj(interp, pElem, &d)) goto createfail;
- p->v[i][Y_IDX] = d;
- }
- if(Odie_Polygon_ComputeArea(interp,p)==TCL_OK) {
- *ptr=p;
- return TCL_OK;
- }
- createfail:
- Tcl_Free((char *)p);
- return TCL_ERROR;
- }
- /* Odie_IsColinear */
- static inline int Odie_IsColinear(double x1,double y1,double x2,double y2,double x3,double y3){
- /* Detect of two lines are colinear */
- if(floatCompare(x1,x3)==0 && floatCompare(y1,y3)==0) {
- return 1;
- }
- double c=(x3-x1)*(y2-y1)-(y3-y1)*(x2-x1);
- if(fabs(c) < __FLT_EPSILON__) return 1;
- return 0;
- }
- /* dist */
- static inline double dist(double x0, double y0, double x1, double y1){
- /*
- ** Return the distance between two points
- */
- double dx = x1 - x0;
- double dy = y1 - y0;
- return sqrt(dx*dx + dy*dy);
- }
- /* withinPolygon */
- static inline int withinPolygon(Odie_Polygon *p, double x, double y){
- /*
- ** Return -1, 0, or 1 if the point x,y is outside, on, or within
- ** the polygon p.
- */
- int res, i;
- /* Do a bounding box check before getting more ellaborate */
- if( x>p->bbox[BBOX_X1_IDX]
- || x<p->bbox[BBOX_X0_IDX]
- || y>p->bbox[BBOX_Y1_IDX]
- || y<p->bbox[BBOX_Y0_IDX]
- ) return -1;
- res = -1;
- for(i=0; i<p->nVertex-1; i++){
- double x0, y0, x1, y1, yP;
- x0 = p->v[i][X_IDX];
- y0 = p->v[i][Y_IDX];
- x1 = p->v[i+1][X_IDX];
- y1 = p->v[i+1][Y_IDX];
- if( x0==x1 ){
- if( x0==x && ((y0<=y && y1>=y) || (y1<=y && y0>=y)) ){
- res = 0;
- break;
- }
- continue;
- }
- if( x0>x1 ){
- int t = x0;
- x0 = x1;
- x1 = t;
- t = y0;
- y0 = y1;
- y1 = t;
- }
- if( x>=x1 || x<x0 ) continue;
- yP = y1 - (x1-x)*(y1-y0)/(x1-x0);
- if( yP == y ){ res = 0; break; }
- if( yP > y ){ res = -res; }
- }
- return res;
- }
- /* Odie_Polygon_XYWithin */
- int Odie_Polygon_XYWithin(Odie_Polygon *p, double x, double y){
- /*
- ** Return -1, 0, or 1 if the point x,y is outside, on, or within
- ** the polygon p.
- */
- return withinPolygon(p,x,y);
- }
- /* Odie_Polygon_VectorXYWithin */
- int Odie_Polygon_VectorXYWithin(Odie_Polygon *p, VectorXY C){
- /*
- ** Return -1, 0, or +1 if the point P is outside, on the border of, or
- ** fully contained within the subcompartment pSub.
- */
- return withinPolygon(p,C[X_IDX],C[Y_IDX]);
- }
- /* Odie_Polygon_ComputeArea */
- int Odie_Polygon_ComputeArea(Tcl_Interp *interp,Odie_Polygon *p){
- double area=0.0;
- double areacomp=0.0;
- int i;
- if( p->v[p->nVertex-1][X_IDX]!=p->v[0][X_IDX] || p->v[p->nVertex-1][Y_IDX]!=p->v[0][Y_IDX] ){
- p->v[p->nVertex][X_IDX] = p->v[0][X_IDX];
- p->v[p->nVertex][Y_IDX] = p->v[0][Y_IDX];
- p->nVertex++;
- }
- for(i=0; i<p->nVertex-1; i++){
- area += 0.5*(p->v[i][Y_IDX] + p->v[i+1][Y_IDX])*(p->v[i+1][X_IDX] - p->v[i][X_IDX]);
- }
- if( area<0.0 ){
- int b, e;
- for(b=0, e=p->nVertex-1; b<e; b++, e--){
- double t;
- t = p->v[b][X_IDX];
- p->v[b][X_IDX] = p->v[e][X_IDX];
- p->v[e][X_IDX] = t;
- t = p->v[b][Y_IDX];
- p->v[b][Y_IDX] = p->v[e][Y_IDX];
- p->v[e][Y_IDX] = t;
- }
- area = -area;
- }
- p->area = area;
- p->bbox[BBOX_X0_IDX] = p->bbox[BBOX_X1_IDX] = p->v[0][X_IDX];
- p->bbox[BBOX_Y1_IDX] = p->bbox[BBOX_Y0_IDX] = p->v[0][Y_IDX];
- for(i=1; i<p->nVertex-1; i++){
- double x, y;
- x = p->v[i][X_IDX];
- if( x<p->bbox[BBOX_X0_IDX] ) p->bbox[BBOX_X0_IDX] = x;
- if( x>p->bbox[BBOX_X1_IDX] ) p->bbox[BBOX_X1_IDX] = x;
- y = p->v[i][Y_IDX];
- if( y>p->bbox[BBOX_Y1_IDX] ) p->bbox[BBOX_Y1_IDX] = y;
- if( y<p->bbox[BBOX_Y0_IDX] ) p->bbox[BBOX_Y0_IDX] = y;
- }
- areacomp=(p->bbox[BBOX_X1_IDX] - p->bbox[BBOX_X0_IDX])*(p->bbox[BBOX_Y1_IDX]-p->bbox[BBOX_Y0_IDX])*1.00001;
- p->center[X_IDX]=(p->bbox[BBOX_X1_IDX]-p->bbox[BBOX_X0_IDX])*0.5+p->bbox[BBOX_X0_IDX];
- p->center[Y_IDX]=(p->bbox[BBOX_Y1_IDX]-p->bbox[BBOX_Y0_IDX])*0.5+p->bbox[BBOX_Y0_IDX];
- if(area<=areacomp) {
- return TCL_OK;
- } else {
- char errstr[256];
- sprintf(errstr,"Area: %g Calculated: %g\n",area,areacomp);
- Tcl_AppendResult(interp, "Area of polygon wonky ", errstr, 0);
- return TCL_ERROR;
- }
- }
- /* Odie_Poly_Compare */
- int Odie_Poly_Compare(Odie_Polygon *polyA,Odie_Polygon *polyB){
- int i,j,N;
- if(!polyA || !polyB) {
- return 0;
- }
- if(polyA->nVertex!=polyB->nVertex) {
- return 0;
- }
- N=polyA->nVertex;
- for(i=0;i<N;i++) {
- if(VectorXY_SamePoint(polyA->v[i],polyB->v[0])) {
- /* Check in either direction */
- for(j=1;j<N;j++) {
- if(
- VectorXY_SamePoint(polyA->v[(i+j)%N],polyB->v[j])==0
- &&
- VectorXY_SamePoint(polyA->v[(i-j)%N],polyB->v[j])==0
- ) {
- return 0;
- }
- }
- /* If we got here we pass */
- return 1;
- }
- }
- return 0;
- }
- /* *Odie_FaceXYZ_ToDict */
- Tcl_Obj *Odie_FaceXYZ_ToDict(Odie_FaceXYZ *pPoly){
- Tcl_Obj *element=Tcl_NewObj();
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pPoly->id);
- Odie_DictObjPut(NULL,element,"id",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewDoubleObj(pPoly->area);
- Odie_DictObjPut(NULL,element,"area",value);
- }
- {
- Tcl_Obj *value;
- Odie_MatrixObj *C;
- if(pPoly->is_2d) {
- C=Odie_MatrixObj_Create(MATFORM_bbox_xy);
- VectorXY_BBOX_Copy(C->matrix,pPoly->bbox_uv);
- value=Matrix_To_TclObj(C);
- } else {
- C=Odie_MatrixObj_Create(MATFORM_aabb_xyz);
- VectorXYZ_AABB_Copy(C->matrix,pPoly->bbox_xyz);
- value=Matrix_To_TclObj(C);
- }
- Odie_DictObjPut(NULL,element,"bbox",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pPoly->bend);
- Odie_DictObjPut(NULL,element,"bend",value);
- }
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pPoly->center);
- Odie_DictObjPut(NULL,element,"center",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pPoly->is_convex);
- Odie_DictObjPut(NULL,element,"is_2d",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pPoly->is_convex);
- Odie_DictObjPut(NULL,element,"is_convex",value);
- }
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pPoly->normal);
- Odie_DictObjPut(NULL,element,"normal",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pPoly->nVertex);
- Odie_DictObjPut(NULL,element,"nVertex",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewDoubleObj(pPoly->radius);
- Odie_DictObjPut(NULL,element,"radius",value);
- }
- {
- Tcl_Obj *value;
- Odie_MatrixObj *C;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Copy(C->matrix,pPoly->rotation);
- value=Matrix_To_TclObj(C);
- Odie_DictObjPut(NULL,element,"rotation",value);
- }
- {
- Tcl_Obj *value;
- Odie_MatrixObj *C;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Copy(C->matrix,pPoly->rotation_inv);
- value=Matrix_To_TclObj(C);
- Odie_DictObjPut(NULL,element,"rotation_inv",value);
- }
- return element;}
- /* Odie_FaceXYZ_freeIntRepProc */
- void Odie_FaceXYZ_freeIntRepProc(Tcl_Obj *objPtr){
- Odie_Free(objPtr->internalRep.otherValuePtr);
- objPtr->internalRep.otherValuePtr=NULL;
- objPtr->typePtr=NULL;
- }
- /* Odie_FaceXYZ_dupIntRepProc */
- void Odie_FaceXYZ_dupIntRepProc(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr){
- Odie_FaceXYZ *src=srcPtr->internalRep.otherValuePtr;
- Odie_FaceXYZ *copy=Odie_FaceXYZ_Create(src->nVertex);
- memcpy(copy,src,src->alloc_bytes);
- Tcl_InvalidateStringRep(dupPtr);
- dupPtr->typePtr=srcPtr->typePtr;
- dupPtr->internalRep.otherValuePtr=copy;
- }
- /* Odie_FaceXYZ_updateStringProc */
- void Odie_FaceXYZ_updateStringProc(Tcl_Obj *objPtr){
- /* Update String Rep */
- char outbuffer[256];
- Tcl_DString result;
- Odie_FaceXYZ *p=objPtr->internalRep.otherValuePtr;
- int i,n;
- Tcl_DStringInit(&result);
- n=p->nVertex;
- /* Express as 3d */
- for(i=0; i<n; i++){
- sprintf(outbuffer,"%g %g %g",(float)p->vertex_xyz[i][X_IDX],(float)p->vertex_xyz[i][Y_IDX],(float)p->vertex_xyz[i][Z_IDX]);
- Tcl_DStringAppendElement(&result,outbuffer);
- }
- objPtr->length=Tcl_DStringLength(&result);
- objPtr->bytes=Odie_Alloc(objPtr->length+1);
- strcpy(objPtr->bytes,Tcl_DStringValue(&result));
- Tcl_DStringFree(&result);
- }
- /* Odie_FaceXYZ_setFromAnyProc */
- int Odie_FaceXYZ_setFromAnyProc(Tcl_Interp *interp,Tcl_Obj *objPtr){
- /* Set internal rep from any Tcl_Obj */
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&Odie_FaceXYZ_setFromAnyProc && objPtr->internalRep.otherValuePtr) {
- /*
- ** Object is already of the type requested
- */
- return TCL_OK;
- }
- }
- Odie_FaceXYZ *p;
- int created=0;
- if(Odie_FaceXYZ_GetFromTclObj(interp,objPtr,&p,&created)) {
- return TCL_ERROR;
- }
- Tcl_InvalidateStringRep(objPtr);
- objPtr->internalRep.otherValuePtr=p;
- objPtr->typePtr=&odie_polygon_tclobjtype;
- return TCL_OK;
- }
- /* *Odie_FaceXYZ_NewTclObj */
- Tcl_Obj *Odie_FaceXYZ_NewTclObj(Odie_FaceXYZ *pPolygon){
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- pResult->internalRep.otherValuePtr=pPolygon;
- pResult->typePtr=&odie_polygon_tclobjtype;
- Tcl_InvalidateStringRep(pResult);
- Tcl_IncrRefCount(pResult);
- return pResult;
- }
- /* *Odie_FaceXYZ_Create */
- Odie_FaceXYZ *Odie_FaceXYZ_Create(int nVertex){
- void *ptr;
- Odie_FaceXYZ *p;
- size_t size;
- int maxVertex=nVertex+2; /* Allocate room for an additional 2 vertices */
- if(nVertex<3) {
- nVertex=3;
- maxVertex=nVertex+2;
- }
- size=sizeof(*p)+maxVertex*sizeof(VectorXYZ)+maxVertex*sizeof(VectorXYZ);
- ptr=Odie_Alloc(size);
- p=(Odie_FaceXYZ *)ptr;
- p->alloc_bytes=size;
- p->maxVertex=maxVertex;
- p->nVertex=nVertex;
- p->vertex_uv=(ptr+sizeof(*p));
- p->vertex_xyz=(ptr+sizeof(*p)+maxVertex*sizeof(VectorXYZ));
- return p;
- }
- /* Odie_FaceXYZ_FromXYList */
- int Odie_FaceXYZ_FromXYList(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_FaceXYZ **ptr){
- int k,i,nVertex;
- Tcl_Obj *pElem;
- Odie_FaceXYZ *p;
- if( Tcl_ListObjLength(interp, objPtr, &k) ) return TCL_ERROR;
- /* Read in a series of doubles a X Y pairs */
- if( k<6 ){
- Tcl_AppendResult(interp, "need at least 3 vertices", 0);
- return TCL_ERROR;
- }
- if( k&1 ){
- Tcl_AppendResult(interp, "coordinates should come in pairs", 0);
- return TCL_ERROR;
- }
- nVertex=k/2;
- p=Odie_FaceXYZ_Create(nVertex);
- for(i=0; i<nVertex; i++){
- double d;
- Tcl_ListObjIndex(0, objPtr, i*2, &pElem);
- if(Tcl_GetDoubleFromObj(interp, pElem, &d)) goto createfail;
- p->vertex_xyz[i][X_IDX] = d;
- Tcl_ListObjIndex(0, objPtr, i*2+1, &pElem);
- if(Tcl_GetDoubleFromObj(interp, pElem, &d)) goto createfail;
- p->vertex_xyz[i][Y_IDX] = d;
- p->vertex_xyz[i][Z_IDX] = 0.0;
- }
- if(Odie_FaceXYZ_Compute(interp,p)) goto createfail;
- *ptr=p;
- return TCL_OK;
- createfail:
- Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Odie_FaceXYZ_FromPoly */
- int Odie_FaceXYZ_FromPoly(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_FaceXYZ **ptr){
- int k,i,nVertex;
- Tcl_Obj *pElem;
- Odie_FaceXYZ *p;
- Odie_Polygon *poly;
- poly=objPtr->internalRep.otherValuePtr;
- nVertex=poly->nVertex;
- p=Odie_FaceXYZ_Create(nVertex);
- for(i=0; i<nVertex; i++){
- VectorXY_Copy(p->vertex_xyz[i],poly->v[i]);
- p->vertex_xyz[i][Z_IDX] = 0.0;
- }
- if(Odie_FaceXYZ_Compute(interp,p)) goto createfail;
- *ptr=p;
- return TCL_OK;
- createfail:
- Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Odie_FaceXYZ_FromVectorList */
- int Odie_FaceXYZ_FromVectorList(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_FaceXYZ **ptr){
- int k,i,nVertex;
- Tcl_Obj *pElem;
- Odie_FaceXYZ *p;
- if( Tcl_ListObjLength(interp, objPtr, &k) ) return TCL_ERROR;
- if( k<3 ){
- Tcl_AppendResult(interp, "need at least 3 vertices", 0);
- return TCL_ERROR;
- }
- nVertex=k;
- p=Odie_FaceXYZ_Create(nVertex);
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjIndex(0, objPtr, i, &pElem);
- if(Odie_GetVectorXYZFromTclObj(interp,pElem,p->vertex_xyz[i])) goto createfail;
- }
- if(Odie_FaceXYZ_Compute(interp,p)) goto createfail;
- *ptr=p;
- return TCL_OK;
- createfail:
- Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Odie_ConvexPolygon_GetFromTclObj */
- int Odie_ConvexPolygon_GetFromTclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_FaceXYZ **ptr,int *created){
- int result;
- result=Odie_FaceXYZ_GetFromTclObj(interp,objPtr,ptr,created);
- if(result) {
- return result;
- }
- Odie_FaceXYZ *pPoly=*ptr;
- if(pPoly->is_convex) {
- return TCL_OK;
- }
- if(interp) {
- Tcl_AppendResult(interp,"Polygon is not convex",NULL);
- }
- if(*created) Odie_FaceXYZ_ShimmerOrFree_TclObj(objPtr,*ptr);
- return TCL_ERROR;
- }
- /* Odie_FaceXYZ_GetFromTclObj */
- int Odie_FaceXYZ_GetFromTclObj(Tcl_Interp *interp,Tcl_Obj *objPtr,Odie_FaceXYZ **ptr,int *created){
- *created=1;
- Tcl_Obj *pElem;
- int k,first_element_length;
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&Odie_FaceXYZ_setFromAnyProc && objPtr->internalRep.otherValuePtr) {
- /*
- ** Object is already of the type requested
- */
- *ptr=objPtr->internalRep.otherValuePtr;
- *created=0;
- return TCL_OK;
- }
- if(objPtr->typePtr->setFromAnyProc==&PolygonObj_setFromAnyProc && objPtr->internalRep.otherValuePtr) {
- /* Our first element is encoded as an ODIE vector */
- *created=1;
- return Odie_FaceXYZ_FromPoly(interp,objPtr,ptr);
- }
- }
- *created=1;
- if( Tcl_ListObjLength(interp, objPtr, &k) ) return TCL_ERROR;
- if( k<3 ){
- Tcl_AppendResult(interp, "need at least 3 vertices", 0);
- return TCL_ERROR;
- }
- /* See if our first element is a valid XYZ Coordnate */
- Tcl_ListObjIndex(0, objPtr, 0, &pElem);
- if(pElem->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&MatrixObj_setFromAnyProc && objPtr->internalRep.otherValuePtr) {
- /* Our first element is encoded as an ODIE vector */
- return Odie_FaceXYZ_FromVectorList(interp,objPtr,ptr);
- }
- }
- /* Guess form by the list contents */
- if( Tcl_ListObjLength(interp, pElem, &first_element_length) ) return TCL_ERROR;
- if(first_element_length==1) {
- /* The first element is only 1 element long, guess we have a stream of doubles */
- return Odie_FaceXYZ_FromXYList(interp,objPtr,ptr);
- }
- if(first_element_length==2) {
- /* The first element is 2 element long, guess we have a stream of vectors */
- return Odie_FaceXYZ_FromVectorList(interp,objPtr,ptr);
- }
- if(first_element_length==3) {
- /* The first element is 3 element long, guess we have a stream of vectors */
- return Odie_FaceXYZ_FromVectorList(interp,objPtr,ptr);
- }
- /* Stop trying to quess */
- Tcl_AppendResult(interp, "Cannot intepret input", 0);
- return TCL_ERROR;
- }
- /* Odie_FaceXYZ_ShimmerOrFree_TclObj */
- void Odie_FaceXYZ_ShimmerOrFree_TclObj(Tcl_Obj *objPtr,Odie_FaceXYZ *p){
- if(objPtr->typePtr) {
- if(objPtr->typePtr->setFromAnyProc==&Odie_FaceXYZ_setFromAnyProc) {
- /*
- ** Object is already of the type requested
- */
- return;
- }
- }
- if(Tcl_IsShared(objPtr)) {
- Odie_Free((char *)p);
- return;
- }
- if(objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
- Tcl_FreeInternalRepProc *freeIntRepProc=objPtr->typePtr->freeIntRepProc;
- freeIntRepProc(objPtr);
- }
- objPtr->internalRep.otherValuePtr=p;
- objPtr->typePtr=&odie_polygon_tclobjtype;
- Tcl_IncrRefCount(objPtr);
- return;
- }
- /* Odie_FaceXYZ_Compute */
- int Odie_FaceXYZ_Compute(Tcl_Interp *interp,Odie_FaceXYZ *p){
- double normal_length=0.0;
- int i,j,k,rmax=0,r1;
- double area=0.0;
- double areacomp=0.0;
- int is2d=1;
- VectorXYZ SUM;
- if(p->nVertex<3) {
- if(interp) {
- Tcl_AppendResult(interp,"Polygons need at least 3 vertices",NULL);
- }
- return TCL_ERROR;
- }
- while(VectorXYZ_SamePoint(p->vertex_xyz[p->nVertex-1],p->vertex_xyz[0])) {
- p->nVertex--;
- if(p->nVertex<=0) {
- return TCL_ERROR;
- }
- }
- VectorXYZ_Copy(p->vertex_xyz[p->nVertex],p->vertex_xyz[0]);
- VectorXYZ_Zero(SUM);
- VectorXYZ_Zero(p->normal);
- VectorXYZ_Zero(p->center);
- VectorXYZ_AABB_Reset(p->bbox_xyz);
- for(i=0;i<p->nVertex;i++) {
- VectorXYZ_AABB_Measure(p->vertex_xyz[i],p->bbox_xyz);
- p->center[X_IDX]+=p->vertex_xyz[i][X_IDX];
- p->center[Y_IDX]+=p->vertex_xyz[i][Y_IDX];
- p->center[Y_IDX]+=p->vertex_xyz[i][Z_IDX];
- }
- p->center[X_IDX] /= p->nVertex;
- p->center[Y_IDX] /= p->nVertex;
- p->center[Z_IDX] /= p->nVertex;
- if(fabs(p->bbox_xyz[Z_MAX_IDX])>__FLT_EPSILON__) {
- is2d=0;
- }
- if(fabs(p->bbox_xyz[Z_MIN_IDX])>__FLT_EPSILON__) {
- is2d=0;
- }
- p->is_2d=is2d;
- if(is2d) {
- p->normal[X_IDX]=0.0;
- p->normal[Y_IDX]=0.0;
- p->normal[Z_IDX]=1.0;
- Odie_Affine4x4_Identity(p->rotation);
- Odie_Affine4x4_Identity(p->rotation_inv);
- for(i=0;i<=p->nVertex;i++) {
- VectorXYZ_Copy(p->vertex_uv[i],p->vertex_xyz[i]);
- }
- } else {
- for(i=0,j=1;i<p->nVertex;i++,j++) {
- r1 = VectorXYZ_DistanceSq(p->center, p->vertex_xyz[i]);
- if(r1>rmax) {
- rmax=r1;
- }
- p->normal[X_IDX] += (p->vertex_xyz[j][Y_IDX]-p->vertex_xyz[i][Y_IDX]) * (p->vertex_xyz[j][Z_IDX]+p->vertex_xyz[i][Z_IDX]);
- p->normal[Y_IDX] += (p->vertex_xyz[j][Z_IDX]-p->vertex_xyz[i][Z_IDX]) * (p->vertex_xyz[j][X_IDX]+p->vertex_xyz[i][X_IDX]);
- p->normal[Z_IDX] += (p->vertex_xyz[j][X_IDX]-p->vertex_xyz[i][X_IDX]) * (p->vertex_xyz[j][Y_IDX]+p->vertex_xyz[i][Y_IDX]);
- }
- p->radius=sqrt(rmax);
- normal_length=VectorXYZ_Magnitude(p->normal);
- if(normal_length>0.0) {
- double inv=1.0/normal_length;
- p->normal[X_IDX]*=inv;
- p->normal[Y_IDX]*=inv;
- p->normal[Z_IDX]*=inv;
- }
- AFFINE rotation,translation;
- Odie_Affine_From_Normal(rotation,p->normal);
- Odie_Affine4x4_Translation(translation,p->center);
- Odie_Affine4x4_Multiply(p->rotation_inv,rotation,translation);
- Odie_Affine4x4_Inverse(p->rotation,p->rotation_inv);
- /* Map the Polygon to UV Space */
- for(i=0;i<=p->nVertex;i++) {
- VectorXYZ_MatrixMultiply(p->vertex_uv[i],p->vertex_xyz[i],p->rotation);
- }
- }
- VectorXYZ_Copy(p->vertex_uv[p->nVertex],p->vertex_xyz[0]);
- /* Compute 2d information from the UV coordinates */
- p->is_convex=1;
- for(i=0; i<p->nVertex; i++){
- int bend;
- j=(i+1)%p->nVertex;
- k=(i+2)%p->nVertex;
- bend=VectorXY_BendDirection(p->vertex_uv[i], p->vertex_uv[j], p->vertex_uv[k]);
- if(bend>0 && p->bend<0) {
- p->is_convex=0;
- } else if(bend<0 && p->bend>0) {
- p->is_convex=0;
- }
- p->bend+=bend;
- }
- if(!p->is_convex) {
- /*
- ** A convex polygon is legal,
- ** we just can't answer questions about area and intersections
- */
- return TCL_OK;
- }
- for(i=0; i<p->nVertex; i++){
- area += 0.5*(p->vertex_uv[i][Y_IDX] + p->vertex_uv[i+1][Y_IDX])*(p->vertex_uv[i+1][X_IDX] - p->vertex_uv[i][X_IDX]);
- }
- if( area<0.0 ){
- int b, e;
- for(b=0, e=p->nVertex; b<e; b++, e--){
- double t;
- t = p->vertex_uv[b][X_IDX];
- p->vertex_uv[b][X_IDX] = p->vertex_uv[e][X_IDX];
- p->vertex_uv[e][X_IDX] = t;
- t = p->vertex_uv[b][Y_IDX];
- p->vertex_uv[b][Y_IDX] = p->vertex_uv[e][Y_IDX];
- p->vertex_uv[e][Y_IDX] = t;
- }
- area = -area;
- }
- if(fabs(area)<__FLT_EPSILON__) {
- area=0.0;
- }
- p->area = area;
- p->bbox_uv[BBOX_X0_IDX] = p->bbox_uv[BBOX_X1_IDX] = p->vertex_uv[0][X_IDX];
- p->bbox_uv[BBOX_Y1_IDX] = p->bbox_uv[BBOX_Y0_IDX] = p->vertex_uv[0][Y_IDX];
- for(i=1; i<p->nVertex; i++){
- double x, y;
- x = p->vertex_uv[i][X_IDX];
- if( x<p->bbox_uv[BBOX_X0_IDX] ) p->bbox_uv[BBOX_X0_IDX] = x;
- if( x>p->bbox_uv[BBOX_X1_IDX] ) p->bbox_uv[BBOX_X1_IDX] = x;
- y = p->vertex_uv[i][Y_IDX];
- if( y>p->bbox_uv[BBOX_Y1_IDX] ) p->bbox_uv[BBOX_Y1_IDX] = y;
- if( y<p->bbox_uv[BBOX_Y0_IDX] ) p->bbox_uv[BBOX_Y0_IDX] = y;
- }
- return TCL_OK;
- }
- /* *Odie_FaceXYZ_Simplify */
- Odie_FaceXYZ *Odie_FaceXYZ_Simplify(Odie_FaceXYZ *pPolygonXYZ){
- Odie_FaceXYZ *pNewPolygonXYZ;
- int i,j,k,N;
- pNewPolygonXYZ=Odie_FaceXYZ_Create(pPolygonXYZ->nVertex);
- pNewPolygonXYZ->nVertex=0;
- N=pPolygonXYZ->nVertex;
- /* The first vertex always belongs */
- VectorXYZ_Copy(pNewPolygonXYZ->vertex_xyz[0],pPolygonXYZ->vertex_xyz[0]);
- pNewPolygonXYZ->nVertex++;
- i=1;
- j=(i-1) % N;
- k=(i-2) % N;
- while(i<N) {
- /* Skip identical points */
- while(VectorXYZ_SamePoint(pPolygonXYZ->vertex_xyz[i],pPolygonXYZ->vertex_xyz[j]) && i<N) {
- i++;
- }
- /* Skip colinear points */
- while(VectorXYZ_IsColinear(pPolygonXYZ->vertex_xyz[k],pPolygonXYZ->vertex_xyz[j],pPolygonXYZ->vertex_xyz[i]) && i<N) {
- i++;
- }
- VectorXYZ_Copy(pNewPolygonXYZ->vertex_xyz[i],pPolygonXYZ->vertex_xyz[i]);
- pNewPolygonXYZ->nVertex++;
- k=j;
- j=i;
- i++;
- }
- return pNewPolygonXYZ;
- }
- /* Odie_FaceXYZ_Compare */
- static inline int Odie_FaceXYZ_Compare(Odie_FaceXYZ *A,Odie_FaceXYZ *B){
- Odie_FaceXYZ *pPolyA,*pPolyB;
- int i,j=0,result=1;
- if(!A || !B) return 0;
- if(A==B) return 1;
- pPolyA=Odie_FaceXYZ_Simplify(A);
- pPolyB=Odie_FaceXYZ_Simplify(B);
- if(pPolyA->nVertex!=pPolyB->nVertex) {
- result=0; goto finished;
- }
- for(i=0;i<pPolyA->nVertex;i++) {
- if(VectorXYZ_SamePoint(pPolyA->vertex_xyz[i],pPolyB->vertex_xyz[i])) continue;
- /* Check the reverse */
- j=pPolyA->nVertex-i-1;
- if(!VectorXYZ_SamePoint(pPolyA->vertex_xyz[i],pPolyB->vertex_xyz[j])) {
- result=0;
- goto finished;
- }
- result=-1;
- }
- finished:
- Odie_Free(pPolyA);
- Odie_Free(pPolyB);
- return result;
- }
- /* Odie_FaceXYZ_Coplaner */
- static inline int Odie_FaceXYZ_Coplaner(Odie_FaceXYZ *A,Odie_FaceXYZ *B){
- int i,j,ia=0,ja=0,ka=0;
- if(!A || !B) return 0;
- if(A==B) return 1;
- for(i=0;i<A->nVertex;i++) {
- int c;
- ia=i;
- ja=(i+1) % A->nVertex;
- ka=(i+2) % A->nVertex;
- for(j=0;j<B->nVertex;j++) {
- c=VectorXYZ_IsCoplaner(A->vertex_xyz[ia],A->vertex_xyz[ja],A->vertex_xyz[ka],B->vertex_xyz[j]);
- if(!c) {
- return 0;
- }
- }
- }
- return 1;
- }
- /* PolygonUV_Within */
- static inline int PolygonUV_Within(Odie_FaceXYZ *p, double x, double y){
- /*
- ** Return -1, 0, or 1 if the point x,y is outside, on, or within
- ** the polygon p.
- */
- int res, i;
- res = -1;
- for(i=0; i<p->nVertex-1; i++){
- double x0, y0, x1, y1, yP;
- x0 = p->vertex_uv[i][X_IDX];
- y0 = p->vertex_uv[i][Y_IDX];
- x1 = p->vertex_uv[i+1][X_IDX];
- y1 = p->vertex_uv[i+1][Y_IDX];
- if( x0==x1 ){
- if( x0==x && ((y0<=y && y1>=y) || (y1<=y && y0>=y)) ){
- res = 0;
- break;
- }
- continue;
- }
- if( x0>x1 ){
- int t = x0;
- x0 = x1;
- x1 = t;
- t = y0;
- y0 = y1;
- y1 = t;
- }
- if( x>=x1 || x<x0 ) continue;
- yP = y1 - (x1-x)*(y1-y0)/(x1-x0);
- if( yP == y ){ res = 0; break; }
- if( yP > y ){ res = -res; }
- }
- return res;
- }
- /* Odie_FaceXYZ_Within */
- static inline int Odie_FaceXYZ_Within(Odie_FaceXYZ *p, VectorXYZ POINT){
- VectorXYZ a; /* Temporary variable to map coordinates during rotation */
- /*
- ** Return -1, 0, or 1 if the point x,y is outside, on, or within
- ** the polygonxyz p.
- */
- if(!VectorXYZ_AABB_Within(POINT,p->bbox_xyz)) {
- return -1;
- }
- /*
- ** If we reach here it means that the closest point will be on the
- ** permiter of the triangle. There are three line faces on the
- ** permiter. Try them all.
- */
- int i, j;
- for(i=0;i<p->nVertex;i++) {
- j=(i+1)%p->nVertex;
- if(VectorXYZ_PointIsOnSegment(POINT,p->vertex_xyz[i], p->vertex_xyz[j])) {
- return 0;
- }
- }
- /*
- ** Translate the coordinate to the same rotation as the polygon
- ** and use 2d checks
- */
- VectorXYZ_MatrixMultiply(a,POINT,p->rotation);
- return PolygonUV_Within(p,a[X_IDX],a[Y_IDX]);
- }
- /* Odie_FaceXYZ_IntersectTest */
- static int Odie_FaceXYZ_IntersectTest(Odie_FaceXYZ *p1,Odie_FaceXYZ *p2){
- double area,x,y;
- area = Odie_FaceXYZ_AreaOfIntersection(p1,p2,&x,&y);
- if(area>0) {
- return 1;
- } else {
- return 0;
- }
- }
- /* Odie_FaceXYZ_AreaOfIntersection */
- static double Odie_FaceXYZ_AreaOfIntersection(Odie_FaceXYZ *p1,Odie_FaceXYZ *p2,double *xin,double *yin){
- double area=0;
- double xInside = 0.0, yInside = 0.0;
- double x0, y0, x1, y1, dx, dy, xP, yP, xC, yC;
- int i, j, cnt;
- int score, bestScore;
- static const int n = 50;
- char hit[50][50];
- /* Compute the overlap of the bounding boxes of the two polygons. */
- x0 = p1->bbox_uv[BBOX_X0_IDX] < p2->bbox_uv[BBOX_X0_IDX] ? p2->bbox_uv[BBOX_X0_IDX] : p1->bbox_uv[BBOX_X0_IDX];
- y0 = p1->bbox_uv[BBOX_Y1_IDX] > p2->bbox_uv[BBOX_Y1_IDX] ? p2->bbox_uv[BBOX_Y1_IDX] : p1->bbox_uv[BBOX_Y1_IDX];
- x1 = p1->bbox_uv[BBOX_X1_IDX] > p2->bbox_uv[BBOX_X1_IDX] ? p2->bbox_uv[BBOX_X1_IDX] : p1->bbox_uv[BBOX_X1_IDX];
- y1 = p1->bbox_uv[BBOX_Y0_IDX] < p2->bbox_uv[BBOX_Y0_IDX] ? p2->bbox_uv[BBOX_Y0_IDX] : p1->bbox_uv[BBOX_Y0_IDX];
- /* Divide the intersection of the bounding boxes into a n-by-n grid
- ** and count the number of elements in this grid whose centers fall
- ** within both polygons. This will be our approximation for the
- ** intersection of the polygons themselves.
- */
- dx = (x1-x0)/n;
- dy = (y1-y0)/n;
- cnt = 0;
- xC = yC = 0.0;
- for(i=0; i<n; i++){
- xP = x0 + dx*(i+0.5);
- for(j=0; j<n; j++){
- yP = y0 + dy*(j+0.5);
- if( PolygonUV_Within(p1, xP, yP)>0 && PolygonUV_Within(p2, xP, yP)>0 ){
- cnt++;
- hit[i][j] = 1;
- xC += xP;
- yC += yP;
- }else{
- hit[i][j] = 0;
- }
- }
- }
- /* We need to find a good approximation for the center of the
- ** overlap. Begin by computing the center of mass for the
- ** overlapping region. Then find the point inside the intersection
- ** that is nearest the center of mass.
- */
- if( cnt>0 ){
- area = cnt*(x1-x0)*(y0-y1)/(n*n);
- xC /= cnt;
- yC /= cnt;
- bestScore = -1.0;
- for(i=0; i<n; i++){
- xP = x0 + dx*(i+0.5);
- for(j=0; j<n; j++){
- if( !hit[i][j] ) continue;
- yP = y0 + dy*(j+0.5);
- score = dist(xP,yP,xC,yC);
- if( score<bestScore || bestScore<0.0 ){
- xInside = xP;
- yInside = yP;
- bestScore = score;
- }
- }
- }
- } else {
- area=0.0;
- }
- *xin=xInside;
- *yin=yInside;
- return area;
- }
- /* SegmentSet_Delete */
- static void SegmentSet_Delete(ClientData clientData){
- SegmentSet *pSet=(SegmentSet *)clientData;
- SegmentSetClear(pSet);
- Odie_Free(pSet);
- }
- /* SegmentSet_Clone */
- static int SegmentSet_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- ){
- SegmentSet *src=(SegmentSet*)metadata;
- SegmentSet *dest=(SegmentSet*)Odie_Alloc(sizeof(SegmentSet));
- SegmentSetCopy(dest,src);
- *newMetaData=(ClientData*)dest;
- return TCL_OK;
- }
- /* *Segment_To_Dict */
- Tcl_Obj *Segment_To_Dict(Segment *pSeg){
- Tcl_Obj *element=Tcl_NewObj();
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pSeg->id);
- Odie_DictObjPut(NULL,element,"id:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pSeg->isVirtual);
- Odie_DictObjPut(NULL,element,"virtual:",value);
- }
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pSeg->from);
- Odie_DictObjPut(NULL,element,"from:",value);
- }
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pSeg->to);
- Odie_DictObjPut(NULL,element,"to:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pSeg->isVirtual);
- Odie_DictObjPut(NULL,element,"exported:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pSeg->idLC);
- Odie_DictObjPut(NULL,element,"id_left:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pSeg->idRC);
- Odie_DictObjPut(NULL,element,"id_right:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pSeg->isVirtual);
- Odie_DictObjPut(NULL,element,"ignore:",value);
- }
- {
- Tcl_Obj *value;
- if(pSeg->boundfwd) {
- value=Tcl_NewIntObj(pSeg->boundfwd->faceid);
- } else {
- value=Tcl_NewIntObj(0);
- }
- Odie_DictObjPut(NULL,element,"facefwd:",value);
- }
- {
- Tcl_Obj *value;
- if(pSeg->boundback) {
- value=Tcl_NewIntObj(pSeg->boundback->faceid);
- } else {
- value=Tcl_NewIntObj(0);
- }
- Odie_DictObjPut(NULL,element,"faceback:",value);
- }
- return element;}
- /* *SegmentSet_Insert_XYZ */
- Segment *SegmentSet_Insert_XYZ(SegmentSet *pSet,int id,VectorXYZ A,VectorXYZ B){
- Segment *pSeg;
- if(id>0) {
- if(SegmentSet_FindById(pSet, id)) return NULL;
- }
- VectorXYZ_GridAlign(A,pSet->grid);
- VectorXYZ_GridAlign(B,pSet->grid);
- if(VectorXYZ_SamePoint(A,B)) return NULL;
- SegmentSet_AddVertex(pSet,A);
- SegmentSet_AddVertex(pSet,B);
- pSeg=Segment_FindByLocation(pSet,A,B);
- if(pSeg) return pSeg;
- pSeg=Segment_Create(pSet,id);
- if(pSeg) {
- Segment_SetToFrom(pSet,pSeg,A,B);
- }
- return pSeg;
- }
- /* SegmentSet_Cleanup_Coincident */
- static int SegmentSet_Cleanup_Coincident(SegmentSet *pSet,Segment *pAB){
- Link *qLoop,*qNext;
- int changes=0;
- for(qLoop=pSet->pAll; qLoop; qLoop=qNext){
- int c;
- Segment *pCD;
- pCD = qLoop->pLinkNode;
- qNext = qLoop->pNext;
- VectorXYZ ICEPT;
- VectorXYZ_ClosestPointOnSegment(pAB->from,pAB->to,pCD->from,ICEPT);
- VectorXYZ_GridAlign(ICEPT,pSet->grid);
- if(VectorXYZ_SamePoint(ICEPT,pCD->from)) {
- changes+=SegmentSet_AddVertex(pSet,ICEPT);
- }
- VectorXYZ_ClosestPointOnSegment(pAB->from,pAB->to,pCD->to,ICEPT);
- VectorXYZ_GridAlign(ICEPT,pSet->grid);
- if(VectorXYZ_SamePoint(ICEPT,pCD->to)) {
- changes+=SegmentSet_AddVertex(pSet,ICEPT);
- }
- }
- for(qLoop=pSet->pAll; qLoop; qLoop=qNext){
- int c;
- Segment *pCD;
- pCD = qLoop->pLinkNode;
- qNext = qLoop->pNext;
- VectorXYZ ICEPT1,ICEPT2;
- /* Evaluate lower to higher */
- if(pCD->id == pAB->id) continue;
- c=VectorXYZ_LineLineCoincident(pAB->from,pAB->to,pCD->from,pCD->to,ICEPT1,ICEPT2);
- if(c<=0) continue;
- changes+=SegmentSet_AddVertex(pSet,ICEPT1);
- if(!VectorXYZ_SamePoint(ICEPT1,ICEPT2)) {
- changes+=SegmentSet_AddVertex(pSet,ICEPT2);
- }
- }
- return changes;
- }
- /* Segset_Insert_Polygon */
- int Segset_Insert_Polygon(SegmentSet *pSet,Odie_FaceXYZ *p,int comptid){
- int h,i,j,reversed=0;
- int bend=0;
- if(p->nVertex<3) {
- return TCL_ERROR;
- }
- for(i=0;i<=p->nVertex;i++) {
- VectorXYZ h_uv,i_uv,j_uv;
- j=(i+1)%p->nVertex;
- h=(i-1)%p->nVertex;
- VectorXYZ_MatrixMultiply(h_uv,p->vertex_xyz[h],pSet->rotation);
- VectorXYZ_MatrixMultiply(i_uv,p->vertex_xyz[i],pSet->rotation);
- VectorXYZ_MatrixMultiply(j_uv,p->vertex_xyz[j],pSet->rotation);
- bend+=VectorXY_BendDirection(h_uv, i_uv, j_uv);
- }
- for(i=0;i<=p->nVertex;i++) {
- Segment *pSeg;
- j=(i+1)%p->nVertex;
- h=(i-1)%p->nVertex;
- pSeg=SegmentSet_Insert_XYZ(pSet,-1,p->vertex_xyz[i],p->vertex_xyz[j]);
- if(pSeg) {
- if(VectorXYZ_SamePoint(pSeg->from,p->vertex_xyz[j])) {
- reversed=1;
- }
- pSeg->isVirtual=0;
- /*
- ** Paint the inside edge of the polygon with the comptid
- */
- if(reversed) {
- /* The line inserted into the segment set was backward from what we specified */
- if(bend<=0) {
- /* The polygon was given in a counter clockwise direction */
- pSeg->idRC=comptid;
- } else {
- pSeg->idLC=comptid;
- }
- } else {
- if(bend<=0) {
- /* The polygon was given in a counter clockwise direction */
- pSeg->idRC=comptid;
- } else {
- pSeg->idLC=comptid;
- }
- }
- }
- }
- return TCL_OK;
- }
- /* SegmentSetCopy */
- void SegmentSetCopy(SegmentSet *dest,SegmentSet *src){
- SegmentSetClear(dest);
- memset(dest, 0, sizeof(SegmentSet));
- Link *pLoop, *pNext;
- for(pLoop=src->pAll; pLoop; pLoop=pNext){
- Segment *pAB,*pNewSeg;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- pNewSeg=SegmentSet_Insert_XYZ(dest,pAB->id,pAB->from,pAB->to);
- if(pNewSeg) {
- Segment_Imprint(pAB,pNewSeg);
- }
- }
- }
- /* Segment_OnList */
- static int Segment_OnList(Segment *pSeg, Link *pList){
- while( pList ){
- if( pList->pLinkNode==pSeg ) return 1;
- pList = pList->pNext;
- }
- return 0;
- }
- /* *SegmentSet_FindById */
- static Segment *SegmentSet_FindById(SegmentSet *p, int id){
- int h;
- Link *pLink;
- h = hashInt(id);
- for(pLink = p->hashId[h]; pLink; pLink=pLink->pNext){
- Segment *pSeg=pLink->pLinkNode;
- if( pSeg->id==id ) return pSeg;
- }
- return 0;
- }
- /* *Segment_FindByLocation */
- Segment *Segment_FindByLocation(SegmentSet *pSet, VectorXYZ A, VectorXYZ B){
- /*
- ** Find and return the line segment that goes from A to B. Return NULL
- ** if there is not such line segment
- */
- Link *pX;
- Segment *p;
- int h;
- VectorXYZ_GridAlign(A,pSet->grid);
- h = hashVectorXYZ(A);
- for(pX=pSet->hashFrom[h]; pX; pX=pX->pNext){
- p = pX->pLinkNode;
- if( VectorXYZ_SamePoint(p->from, A) && VectorXYZ_SamePoint(p->to, B) ){
- return p;
- }
- if( VectorXYZ_SamePoint(p->to, A) && VectorXYZ_SamePoint(p->from, B) ){
- return p;
- }
- }
- for(pX=pSet->hashTo[h]; pX; pX=pX->pNext){
- p = pX->pLinkNode;
- if( VectorXYZ_SamePoint(p->from, A) && VectorXYZ_SamePoint(p->to, B) ){
- return p;
- }
- if( VectorXYZ_SamePoint(p->to, A) && VectorXYZ_SamePoint(p->from, B) ){
- return p;
- }
- }
- return 0;
- }
- /* Segment_Imprint */
- static void Segment_Imprint(Segment *pSrc,Segment *pDest){
- if(pSrc==pDest) return;
- pDest->isVirtual=pSrc->isVirtual;
- pDest->idLC=pSrc->idLC;
- pDest->idRC=pSrc->idRC;
- }
- /* Segment_SetToFrom */
- static void Segment_SetToFrom(SegmentSet *pSet, Segment *p, VECTORXYZ from, VECTORXYZ to){
- int h;
- VectorXYZ_GridAlign(from,pSet->grid);
- VectorXYZ_GridAlign(to,pSet->grid);
- if(VectorXYZ_SamePoint(from,p->from) && VectorXYZ_SamePoint(to,p->to)) {
- return;
- }
- LinkRemove(&p->pFrom);
- LinkRemove(&p->pTo);
- pSet->modified=1;
- VectorXYZ_Copy(p->from,from);
- VectorXYZ_Copy(p->to,to);
- VectorXY_BBOX_Measure(p->from,pSet->bbox_uv);
- VectorXY_BBOX_Measure(p->to,pSet->bbox_uv);
- h = hashVectorXYZ(p->from);
- LinkInsert(&pSet->hashFrom[h], &p->pFrom);
- h = hashVectorXYZ(p->to);
- LinkInsert(&pSet->hashTo[h], &p->pTo);
- }
- /* *Segment_Create */
- static inline Segment *Segment_Create(SegmentSet *pSet,int newid){
- Link *pLoop,*pNext;
- Segment *p=NULL;
- int id,h;
- for(pLoop=pSet->pFree; pLoop; pLoop=pNext){
- p=pLoop->pLinkNode;
- pNext=pLoop->pNext;
- if(p) {
- LinkRemove(&p->pFree);
- id=p->id;
- memset(p,0,sizeof(*p));
- if(newid<=0) {
- p->id=id;
- } else if(p->id>pSet->nextid) {
- pSet->nextid=p->id;
- }
- break;
- }
- }
- if(!p) {
- p=(Segment *)Odie_Alloc( sizeof(*p) );
- if(newid<=0) {
- pSet->nextid++;
- p->id=pSet->nextid;
- } else if(p->id>pSet->nextid) {
- pSet->nextid=p->id;
- }
- }
- if(!p) {
- return NULL;
- }
- LinkInit(p->pAll, p);
- LinkInit(p->pSet, p);
- LinkInit(p->pHash, p);
- LinkInit(p->pFrom, p);
- LinkInit(p->pTo, p);
- LinkInit(p->pFree, p);
- LinkInsert(&pSet->pAll, &p->pAll);
- h = hashInt(p->id);
- LinkInsert(&pSet->hashId[h], &p->pHash);
- pSet->modified=1;
- pSet->nSeg++;
- pSet->pCurrent = p;
- return p;
- }
- /* SegmentSetRemove */
- static inline void SegmentSetRemove(SegmentSet *pSet, Segment *p){
- /*
- ** Remove a segment from the segment set
- */
- pSet->modified=1;
- LinkRemove(&p->pAll);
- /* We intentionally do not remove pSeg->pSet because it might not be
- ** a well-formed list */
- LinkRemove(&p->pHash);
- LinkRemove(&p->pFrom);
- LinkRemove(&p->pTo);
- LinkInit(p->pAll, p);
- //LinkInit(p->pSet, p);
- LinkInit(p->pHash, p);
- LinkInit(p->pFrom, p);
- LinkInit(p->pTo, p);
- LinkInsert(&pSet->pFree,&p->pFree);
- pSet->nSeg--;
- if( pSet->pCurrent==p ){
- pSet->pCurrent = pSet->pAll ? pSet->pAll->pLinkNode : 0;
- }
- }
- /* SegRelink */
- static inline void SegRelink(SegmentSet *pSet, Segment *p){
- /*
- ** Call this routine to relink into a segment when the
- ** Seg.from vector changes.
- */
- int h;
- pSet->modified=1;
- LinkRemove(&p->pHash);
- LinkRemove(&p->pFrom);
- LinkRemove(&p->pTo);
- LinkRemove(&p->pFree);
- h = hashInt(p->id);
- LinkInsert(&pSet->hashId[h], &p->pHash);
- h = hashVectorXY(p->from);
- LinkInsert(&pSet->hashFrom[h], &p->pFrom);
- h = hashVectorXY(p->to);
- LinkInsert(&pSet->hashTo[h], &p->pTo);
- }
- /* SegmentSetClear */
- static inline void SegmentSetClear(SegmentSet *pSet){
- /*
- ** Remove all segments from a segment set
- */
- Link *pLoop,*pNext;
- Segment *p;
- SegmentSet_ClearFaceEdgeCache(pSet);
- while( pSet->pAll ){
- assert( pSet->nSeg>0 );
- p=pSet->pAll->pLinkNode;
- SegmentSetRemove(pSet, p);
- }
- for(pLoop=pSet->pFree; pLoop; pLoop=pNext){
- p=pLoop->pLinkNode;
- pNext=pLoop->pNext;
- LinkRemove(&p->pFree);
- Odie_Free((char *)p);
- }
- assert( pSet->nSeg==0 );
- }
- /* SegmentSetStep */
- static inline void SegmentSetStep(SegmentSet *pSet){
- /*
- ** Advance the pSet->pAll pointer so that it is pointing to a different
- ** segment.
- */
- if( pSet->pCurrent ){
- Link *pNext = pSet->pCurrent->pAll.pNext;
- pSet->pCurrent = pNext ? pNext->pLinkNode : 0;
- }
- if( pSet->pCurrent==0 ){
- pSet->pCurrent = pSet->pAll ? pSet->pAll->pLinkNode : 0;
- }
- }
- /* SegmentSet_AddVertex */
- static int SegmentSet_AddVertex(SegmentSet *pSet,VectorXYZ A){
- Link *pLoop,*pNext;
- VectorXYZ B,ICEPT;
- int changes=0;
- VectorXYZ_GridAlign(A,pSet->grid);
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- int delete=0;
- Segment *pAB,*pNew;
- Segment *found;
- pAB = pLoop->pLinkNode;
- pNext=pLoop->pNext;
- if(VectorXYZ_SamePoint(A,pAB->from)) continue;
- if(VectorXYZ_SamePoint(A,pAB->to)) continue;
- VectorXYZ_ClosestPointOnSegment(pAB->from,pAB->to,A,ICEPT);
- if(!VectorXYZ_SamePoint(ICEPT,A)) continue;
- changes++;
- /* Preserve the segment's original destination */
- VectorXYZ_Copy(B,pAB->to);
- found=Segment_FindByLocation(pSet,pAB->from,A);
- if(!found) {
- /* Truncate the first part of the segment */
- Segment_SetToFrom(pSet,pAB,pAB->from,A);
- } else {
- delete=1;
- }
- found=Segment_FindByLocation(pSet,A,B);
- if(!found) {
- if(delete) {
- /*
- ** A segment exists for the first part of this segment
- ** but not the second. Rather than throw this link out
- ** just to re-create it, recycle
- */
- delete=0;
- Segment_SetToFrom(pSet,pAB,A,B);
- } else {
- pNew=SegmentSet_Insert_XYZ(pSet,-1,A,B);
- if(pNew) {
- Segment_Imprint(pAB,pNew);
- }
- }
- }
- if(delete) {
- /* A segment already exists, delete this one */
- SegmentSetRemove(pSet,pAB);
- }
- }
- return changes;
- }
- /* SegmentSet_Cleanup */
- int SegmentSet_Cleanup(SegmentSet *pSet,int looseend){
- Link *pLoop,*pNext;
- Link *qLoop,*qNext;
- Segment *pAB,*pCD;
- int count=0;
- int loop=0;
- int match=0;
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- pAB->test=0;
- }
- /* Cleanup loose ends */
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- VectorXYZ A,B;
- Link *pList;
- int nSeg;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- VectorXYZ_Copy(A,pAB->from);
- VectorXYZ_Copy(B,pAB->to);
- VectorXYZ_GridAlign(A,pSet->grid);
- VectorXYZ_GridAlign(B,pSet->grid);
- Segment_SetToFrom(pSet,pAB,A,B);
- }
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- count+=SegmentSet_Cleanup_Coincident(pSet,pAB);
- }
- if(looseend) {
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- Link *pList;
- int nSeg;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- pList = SegmentSet_Segments_AtVertex(pSet, pAB->from,&nSeg);
- if( nSeg < 2 ){
- pAB->test=1;
- match++;
- }
- pList = SegmentSet_Segments_AtVertex(pSet, pAB->to,&nSeg);
- if( nSeg < 2 ){
- pAB->test=1;
- match++;
- }
- }
- /* Cleanup overlapping walls */
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if(pAB->test) continue;
- if(VectorXYZ_DistanceSq(pAB->from,pAB->to)<pSet->gridSq) {
- pAB->test=1;
- continue;
- }
- for(qLoop=pNext; qLoop; qLoop=qNext){
- pCD = qLoop->pLinkNode;
- qNext = qLoop->pNext;
- if(pCD->test) continue;
- if(VectorXYZ_SamePoint(pAB->from,pCD->from)) {
- if(VectorXYZ_SamePoint(pAB->to,pCD->to)) {
- if(pAB->isVirtual>pCD->isVirtual) {
- pAB->test=1;
- } else if(pAB->id>pCD->id) {
- pAB->test=1;
- } else {
- pCD->test=1;
- }
- continue;
- }
- }
- if(VectorXYZ_SamePoint(pAB->from,pCD->from)) {
- if(VectorXYZ_SamePoint(pAB->to,pCD->to)) {
- if(pAB->isVirtual>pCD->isVirtual) {
- pAB->test=1;
- } else if(pAB->id>pCD->id) {
- pAB->test=1;
- } else {
- pCD->test=1;
- }
- }
- }
- }
- }
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if(pAB->test) {
- SegmentSetRemove(pSet,pAB);
- count++;
- }
- }
- }
- return count;
- }
- /* SegmentSet_Interference_Check */
- static int SegmentSet_Interference_Check(SegmentSet *pSet,VectorXYZ A,VectorXYZ B){
- Link *qLoop,*qNext;
- int onsegment=0;
- for(qLoop=pSet->pAll; qLoop; qLoop=qNext){
- int c;
- Segment *pTest;
- VectorXYZ ICEPT1,ICEPT2;
- qNext = qLoop->pNext;
- pTest = qLoop->pLinkNode;
- if((VectorXYZ_DistanceSq(A,pTest->from) < pSet->gridSq) && (VectorXYZ_DistanceSq(B,pTest->to) < pSet->gridSq)) return 3;
- if((VectorXYZ_DistanceSq(A,pTest->to) < pSet->gridSq) && (VectorXYZ_DistanceSq(B,pTest->from) < pSet->gridSq)) return 3;
- if(VectorXYZ_PointIsOnSegment(A,pTest->from,pTest->to)) {
- onsegment++;
- continue;
- }
- c=VectorXYZ_LineLineCoincident(A,B,pTest->from,pTest->to,ICEPT1,ICEPT2);
- if(c>0) {
- return c;
- }
- }
- /* If the ray did not touch any segment return a unique error code */
- if(onsegment==0) {
- return 16;
- }
- return 0;
- }
- /* SegmentSet_Edge_Connection */
- static int SegmentSet_Edge_Connection(SegmentSet *pSet,VectorXYZ A,int comptid,VectorXYZ RESULT){
- Link *pLoop,*pNext;
- Segment *pAB,*pBest=NULL;
- VectorXYZ ICEPT;
- double pBestDist=HUGE_VAL;
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- double score;
- int interference;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if(comptid!=0 && pAB->idRC!=comptid && pAB->idLC!=comptid) {
- continue;
- }
- VectorXYZ_ClosestPointOnSegment(pAB->from,pAB->to,A,ICEPT);
- VectorXYZ_GridAlign(ICEPT,pSet->grid);
- score=VectorXYZ_DistanceSq(A,ICEPT);
- if(score<pSet->gridSq) continue;
- interference=SegmentSet_Interference_Check(pSet,A,ICEPT);
- if(interference>0) continue;
- if(!pBest || score<pBestDist) {
- pBest=pAB;
- pBestDist=score;
- VectorXYZ_Copy(RESULT,ICEPT);
- }
- }
- if(pBest) {
- return TCL_OK;
- }
- return TCL_ERROR;
- }
- /* Segment_Compute_UV */
- inline extern void Segment_Compute_UV(SegmentSet *pSet,Segment *pSeg,VectorXYZ uvfrom,VectorXYZ uvto){
- VectorXYZ_MatrixMultiply(uvfrom,pSeg->from,pSet->rotation);
- VectorXYZ_MatrixMultiply(uvto,pSeg->to,pSet->rotation);
- }
- /* SegmentSet_Convex_Connection */
- static int SegmentSet_Convex_Connection(SegmentSet *pSet,Segment *pAB,int back,VectorXYZ RESULT){
- Link *pLoop;
- Segment *pCD,*pBest=NULL;
- VectorXYZ A,B,AB,C,ICEPT,A_UV,B_UV,C_UV;
- double pBestAngle=4*M_PI;
- double pBestDist=HUGE_VAL;
- double angle,rangle,len;
- double rightangle=M_PI*0.5;
- int ortho=0,i;
- /* Try to ray cast the vector and find an intercept continuing along the line */
- if(back) {
- VectorXYZ_Copy(A,pAB->to);
- VectorXYZ_Copy(B,pAB->from);
- } else {
- VectorXYZ_Copy(A,pAB->from);
- VectorXYZ_Copy(B,pAB->to);
- }
- VectorXYZ_MatrixMultiply(A_UV,A,pSet->rotation);
- VectorXYZ_MatrixMultiply(B_UV,B,pSet->rotation);
- VectorXYZ_Subtract(AB,A_UV,B_UV);
- len=pSet->grid;
- angle=atan2(AB[Y_IDX],AB[X_IDX]);
- for(i=-1;i<1;i++) {
- rangle=angle+(M_PI*0.5*i);
- rangle-=fmod(rangle,M_PI*0.5);
- C_UV[X_IDX]=A_UV[X_IDX]+cos(rangle)*len;
- C_UV[Y_IDX]=A_UV[Y_IDX]+sin(rangle)*len;
- C_UV[Z_IDX]=A_UV[Z_IDX];
- VectorXYZ_MatrixMultiply(C,C_UV,pSet->rotation_inv);
- for(pLoop=pSet->pAll; pLoop; pLoop=pLoop->pNext){
- double x,y;
- int c;
- VectorXYZ ICEPT1,ICEPT2;
- pCD = pLoop->pLinkNode;
- if(pCD->ignore) continue;
- if(pCD==pAB) continue;
- if(VectorXYZ_SamePoint(pAB->from,pCD->from)) continue;
- if(VectorXYZ_SamePoint(pAB->from,pCD->to)) continue;
- if(VectorXYZ_SamePoint(pAB->to,pCD->from)) continue;
- if(VectorXYZ_SamePoint(pAB->to,pCD->to)) continue;
- c=VectorXYZ_LineLineIntersect(A,C,pCD->from,pCD->to,ICEPT1,ICEPT2,&x,&y);
- if(c>0) {
- int interference;
- double score;
- if(!VectorXYZ_PointIsOnSegment(ICEPT1,pCD->from,pCD->to)) {
- interference=16;
- } else {
- interference=SegmentSet_Interference_Check(pSet,A,ICEPT1);
- }
- if(interference<=0) {
- if(fabs(angle-rangle)<pBestAngle) {
- score=VectorXYZ_Distance(A,ICEPT1);
- if(score>(pSet->grid*10) && (!pBest || score<pBestDist)) {
- pBest=pCD;
- pBestDist=score;
- VectorXYZ_Copy(RESULT,ICEPT1);
- pBestAngle=rangle;
- }
- }
- }
- if(!VectorXYZ_PointIsOnSegment(ICEPT2,pCD->from,pCD->to)) {
- interference=16;
- } else {
- interference=SegmentSet_Interference_Check(pSet,A,ICEPT2);
- }
- if(interference<=0) {
- if(fabs(angle-rangle)<pBestAngle) {
- score=VectorXYZ_DistanceSq(A,ICEPT2);
- if(score>(pSet->grid*10) && (!pBest || score<pBestDist)) {
- pBest=pCD;
- pBestDist=score;
- VectorXYZ_Copy(RESULT,ICEPT2);
- pBestAngle=rangle;
- }
- }
- }
- }
- }
- }
- if(pBest) {
- return TCL_OK;
- }
- return TCL_ERROR;
- }
- /* SegmentSetNextBend */
- static int SegmentSetNextBend(
- SegmentSet *pSet,
- Segment *pAB,
- int backwards,
- Segment **ppSeg, /* OUT: First segment clockwise from xR,yR->xV,yV */
- int *pfBack, /* OUT: True if output segment goes backwards */
- int *pfBend, /* OUT: Bend direction */
- double *pfAngle
- ){
- Segment *pSegThis;
- int thisBack,thisBend;
- double thisAngle;
- pSegThis=pAB;
- thisBack=backwards;
- thisBend=0;
- while(thisBend==0) {
- if(SegmentSetNext(pSet, pSegThis, thisBack,ppSeg,pfBack,pfBend,pfAngle)) {
- return TCL_ERROR;
- }
- thisBack=*pfBack;
- thisBend=*pfBend;
- if(thisBend==0) {
- pSegThis->isBoundary=1;
- }
- pSegThis=*ppSeg;
- }
- return TCL_OK;
- }
- /* SegmentSet_SelfCheck */
- static int SegmentSet_SelfCheck(Tcl_Interp *interp, SegmentSet *p){
- Link *pLink;
- Segment *pSeg;
- int h;
- char zErr[200];
- for(pLink=p->pAll; pLink; pLink=pLink->pNext){
- pSeg = pLink->pLinkNode;
- h = hashInt(pSeg->id);
- if(!Segment_OnList(pSeg, p->hashId[h]) ){
- sprintf(zErr, "segment %d missing from hashId[%d]", pSeg->id, h);
- Tcl_SetResult(interp, zErr, TCL_VOLATILE);
- return TCL_ERROR;
- }
- h = hashCoord(pSeg->from[X_IDX], pSeg->from[Y_IDX]);
- if(!Segment_OnList(pSeg, p->hashFrom[h]) ){
- sprintf(zErr, "segment %d missing from hashFrom[%d]", pSeg->id, h);
- Tcl_SetResult(interp, zErr, TCL_VOLATILE);
- return TCL_ERROR;
- }
- h = hashCoord(pSeg->to[X_IDX], pSeg->to[Y_IDX]);
- if(!Segment_OnList(pSeg, p->hashTo[h]) ){
- sprintf(zErr, "segment %d missing from hashTo[%d]", pSeg->id, h);
- Tcl_SetResult(interp, zErr, TCL_VOLATILE);
- return TCL_ERROR;
- }
- }
- return TCL_OK;
- }
- /* *SegmentSet_Segments_AtVertex */
- static Link *SegmentSet_Segments_AtVertex(SegmentSet *p, VectorXYZ point,int *nSeg){
- Link *pList = 0;
- Link *pI;
- int h,count=0;
- VectorXYZ_GridAlign(point,p->grid);
- h = hashVectorXYZ(point);
- for(pI=p->hashFrom[h]; pI; pI=pI->pNext){
- Segment *pSeg = pI->pLinkNode;
- if( pSeg->ignore_fwd ) continue;
- if(VectorXYZ_SamePoint(point,pSeg->from)) {
- //assert( !segmentOnList(pSeg, pList) );
- count++;
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- }
- for(pI=p->hashTo[h]; pI; pI=pI->pNext){
- Segment *pSeg = pI->pLinkNode;
- if( pSeg->ignore_back ) continue;
- if(VectorXYZ_SamePoint(point,pSeg->to)) {
- //assert( !segmentOnList(pSeg, pList) );
- count++;
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- }
- *nSeg=count;
- return pList;
- }
- /* SegmentSetNext */
- static int SegmentSetNext(
- SegmentSet *pSet,
- Segment *pAB,
- int backwards,
- Segment **ppSeg, /* OUT: First segment clockwise from xR,yR->xV,yV */
- int *pfBack, /* OUT: True if output segment goes backwards */
- int *pfBend, /* OUT: Bend direction */
- double *pfAngle
- ){
- VectorXYZ remote,vertex,remote_uv,vertex_uv;
- Link *pI,*vList;
- int i,best=-1;
- int nSeg=0;
- struct {
- Segment *pSeg;
- int isBack;
- double angle;
- int bend;
- int edge;
- VectorXYZ uv_remote;
- } *aSeg, aSegStatic[20];
- /*
- pAB->ignore_fwd=1;
- pAB->ignore_back=1;
- */
- if(backwards) {
- VectorXYZ_Copy(remote,pAB->to);
- VectorXYZ_Copy(vertex,pAB->from);
- } else {
- VectorXYZ_Copy(remote,pAB->from);
- VectorXYZ_Copy(vertex,pAB->to);
- }
- VectorXYZ_MatrixMultiply(remote_uv,remote,pSet->rotation);
- VectorXYZ_MatrixMultiply(vertex_uv,vertex,pSet->rotation);
- vList=SegmentSet_Segments_AtVertex(pSet,vertex,&nSeg);
- if(nSeg==0) {
- *ppSeg=NULL;
- *pfBack=0;
- *pfBend=2;
- *pfAngle=2*M_PI;
- return TCL_ERROR;
- }
- if( nSeg<=sizeof(aSegStatic)/sizeof(aSegStatic[0]) ){
- aSeg = aSegStatic;
- }else{
- aSeg = (void *)Odie_Alloc( nSeg*sizeof(*aSeg) );
- }
- for(pI=vList, i=0; pI; i++, pI=pI->pNext){
- Segment *pSeg;
- aSeg[i].pSeg = pSeg = pI->pLinkNode;
- if( VectorXYZ_SamePoint(pSeg->from,vertex)) {
- aSeg[i].isBack = 0;
- aSeg[i].edge=pSeg->isVirtual||(pSeg->idRC>0);
- VectorXYZ_MatrixMultiply(aSeg[i].uv_remote,pSeg->to,pSet->rotation);
- } else {
- aSeg[i].isBack = 1;
- aSeg[i].edge=pSeg->isVirtual||(pSeg->idLC>0);
- VectorXYZ_MatrixMultiply(aSeg[i].uv_remote,pSeg->from,pSet->rotation);
- }
- if(VectorXYZ_SamePoint(aSeg[i].uv_remote,remote)) {
- aSeg[i].angle = 2*M_PI;
- aSeg[i].bend = -2;
- } else {
- aSeg[i].angle = VectorXY_Angle_Three_Point(remote_uv, vertex_uv, aSeg[i].uv_remote);
- aSeg[i].bend = VectorXY_BendDirection(remote_uv, vertex_uv, aSeg[i].uv_remote);
- }
- }
- best=0;
- for(i=1;i<nSeg;i++) {
- if(aSeg[i].angle<aSeg[best].angle) {
- best=i;
- }
- }
- *ppSeg=aSeg[best].pSeg;
- *pfBack=aSeg[best].isBack;
- *pfBend=aSeg[best].bend;
- *pfAngle=aSeg[best].angle;
- if( aSeg!=aSegStatic ){
- Tcl_Free((char *) aSeg );
- }
- return TCL_OK;
- }
- /* SegmentSet_ClearFaceEdgeCache */
- static void SegmentSet_ClearFaceEdgeCache(SegmentSet *pSet){
- if(!pSet->aBoundary) return;
- Odie_Free(pSet->aBoundary);
- pSet->aBoundary=NULL;
- pSet->modified=0;
- }
- /* FaceBoundary_Mark_Degenerate */
- static void FaceBoundary_Mark_Degenerate(FaceBoundary *pFace,int code){
- FaceBoundary *qFace,*pFaceNext;
- for(qFace=pFace;qFace;qFace=pFaceNext) {
- pFaceNext=qFace->pNext;
- qFace->pNext=NULL;
- qFace->isloop=0;
- qFace->faceid=qFace->id;
- }
- pFace->faceid=pFace->id;
- pFace->nSeg=1;
- pFace->isloop=code;
- pFace->pNext=NULL;
- }
- /* SegmentSet_BuildFaceEdgeCache_ExpandRight */
- static int SegmentSet_BuildFaceEdgeCache_ExpandRight(SegmentSet *pSet,int faceid,int stage){
- FaceBoundary *sFace;
- FaceBoundary *pFace;
- FaceBoundary *oFace=NULL;
- Link *pLoop;
- VectorXYZ start;
- Segment *pSeg,*pAB,*pBC;
- int pbcback,pbcbend,idx;
- double pbcangle;
- sFace=pFace=&pSet->aBoundary[faceid];
- /*
- ** If this boundary is part of a loop, or the end of a loop continue
- */
- if(sFace->pNext || sFace->isloop>0) {
- return 0;
- }
- /*
- ** Don't expand the backface of real walls until stage 2
- */
- if(stage<1 && !sFace->pSeg->isVirtual) {
- if(sFace->outside_edge) return 0;
- }
- /*
- ** Detect degenerate loops if they wrap back to a different point
- ** than our starting point. Reset the flag we use to detect that.
- */
- for(idx=0;idx<(pSet->nSeg*2);idx++) {
- pSet->aBoundary[idx].parsed=0;
- pSet->aBoundary[idx].pSeg->ignore=0;
- pSet->aBoundary[idx].pSeg->ignore_fwd=0;
- pSet->aBoundary[idx].pSeg->ignore_back=0;
- pSet->aBoundary[idx].angle=0;
- }
- sFace->nSeg=1;
- sFace->facebend=0;
- pSeg=pAB=sFace->pSeg;
- if(pFace->backwards) {
- VectorXYZ_Copy(start,pSeg->to);
- } else {
- VectorXYZ_Copy(start,pSeg->from);
- }
- while(pAB) {
- int atstart=0;
- if(SegmentSetNext(pSet,pAB,pFace->backwards,&pBC,&pbcback,&pbcbend,&pbcangle)) {
- /*
- ** If this case occurs, we reached the end of the line without
- ** returning to the start. Mark this section as degenerate
- */
- FaceBoundary_Mark_Degenerate(sFace,3);
- return 1;
- }
- if(!pBC) {
- FaceBoundary_Mark_Degenerate(sFace,4);
- return 1;
- }
- /*
- ** If we have returned to the start mark the beginning and end
- ** of the loop
- */
- if(pbcback) {
- oFace=pBC->boundback;
- atstart=VectorXYZ_SamePoint(start,pBC->to);
- } else {
- oFace=pBC->boundfwd;
- atstart=VectorXYZ_SamePoint(start,pBC->from);
- }
- if(oFace==sFace || atstart) {
- sFace->isloop=1;
- sFace->nSeg++;
- if(sFace->nSeg<3) {
- FaceBoundary_Mark_Degenerate(sFace,0);
- } else {
- pFace->faceid=faceid;
- pFace->pNext=oFace;
- pFace->isloop=2;
- }
- return 1;
- }
- if(oFace->parsed) {
- /*
- ** This loop has encountered a knot
- */
- FaceBoundary_Mark_Degenerate(sFace,0);
- return 1;
- }
- if(oFace->faceid!=oFace->id) {
- /*
- ** This loop has bumped up against a different loop
- ** Try to find another vertex
- */
- if(stage<2) {
- FaceBoundary_Mark_Degenerate(sFace,0);
- return 1;
- } else {
- if(oFace->backwards) {
- oFace->pSeg->ignore_back=1;
- } else {
- oFace->pSeg->ignore_fwd=1;
- }
- continue;
- }
- }
- if(VectorXYZ_SamePoint(pAB->from,pBC->to)) {
- if(VectorXYZ_SamePoint(pBC->from,pAB->to)) {
- if(oFace->backwards) {
- oFace->pSeg->ignore_back=1;
- } else {
- oFace->pSeg->ignore_fwd=1;
- }
- continue;
- }
- }
- sFace->facebend+=pbcbend;
- oFace->parsed=1;
- /*
- ** Add this segment to the end of the list and
- ** mark the segment as part of the same face
- */
- pFace->faceid=faceid;
- pFace->pNext=oFace;
- oFace->faceid=faceid;
- oFace->bend=pbcbend;
- oFace->angle=pbcangle;
- sFace->nSeg++;
- pAB=pBC;
- pFace=oFace;
- }
- return 1;
- }
- /* SegmentSet_BuildFaceEdgeCache */
- static void SegmentSet_BuildFaceEdgeCache(SegmentSet *pSet){
- Link *pLoop;
- int nBound=0;
- int i,changes=0,count=0;
- size_t asize;
- if(pSet->modified) {
- SegmentSet_ClearFaceEdgeCache(pSet);
- SegmentSet_Cleanup(pSet,0);
- } else {
- /* Return immediately if the cache already exists */
- if(pSet->aBoundary) {
- return;
- }
- }
- nBound=(pSet->nSeg*2);
- asize=sizeof(FaceBoundary)*nBound;
- pSet->aBoundary=(FaceBoundary *)Odie_Alloc(asize);
- i=nBound=0;
- for(pLoop=pSet->pAll; pLoop; pLoop=pLoop->pNext){
- Segment *pSeg=pLoop->pLinkNode;
- if(!pSeg->idRC && !pSeg->idLC) {
- pSeg->isVirtual=1;
- }
- pSeg->ignore_fwd=0;
- pSeg->ignore_back=0;
- pSeg->boundfwd=&pSet->aBoundary[i];
- pSet->aBoundary[i].id=i;
- pSet->aBoundary[i].pSeg=pSeg;
- pSet->aBoundary[i].nSeg=0;
- pSet->aBoundary[i].backwards=0;
- pSet->aBoundary[i].isloop=0;
- pSet->aBoundary[i].facebend=0;
- pSet->aBoundary[i].pNext=NULL;
- pSet->aBoundary[i].bend=2;
- if(pSeg->idLC<0) {
- pSet->aBoundary[i].inside_edge=0;
- pSet->aBoundary[i].outside_edge=1;
- } else {
- if(pSeg->idLC>0) {
- pSet->aBoundary[i].inside_edge=1;
- pSet->aBoundary[i].outside_edge=0;
- } else if(pSeg->idRC>0) {
- pSet->aBoundary[i].inside_edge=0;
- pSet->aBoundary[i].outside_edge=1;
- }
- }
- i++;
- pSeg->boundback=&pSet->aBoundary[i];
- pSet->aBoundary[i].id=i;
- pSet->aBoundary[i].pSeg=pSeg;
- pSet->aBoundary[i].nSeg=0;
- pSet->aBoundary[i].backwards=1;
- pSet->aBoundary[i].isloop=0;
- pSet->aBoundary[i].facebend=0;
- pSet->aBoundary[i].pNext=NULL;
- pSet->aBoundary[i].bend=2;
- if(pSeg->idRC<0) {
- pSet->aBoundary[i].inside_edge=0;
- pSet->aBoundary[i].outside_edge=1;
- } else {
- if(pSeg->idRC>0) {
- pSet->aBoundary[i].inside_edge=1;
- pSet->aBoundary[i].outside_edge=0;
- } else if(pSeg->idLC>0) {
- pSet->aBoundary[i].inside_edge=0;
- pSet->aBoundary[i].outside_edge=1;
- }
- }
- i++;
- }
- nBound=i;
- /* Incubation stage. Let the clear cut winners take shape */
- changes=0;
- /* On the first pass ignore backfaces for "real" panels */
- for(count=0;count<nBound;count++) {
- if(count>0 && changes==0) {
- break;
- }
- changes=0;
- for(i=0;i<nBound;i++) {
- changes+=SegmentSet_BuildFaceEdgeCache_ExpandRight(pSet,i,0);
- }
- }
- /* On the second pass include backfaces for real panels */
- for(count=0;count<nBound;count++) {
- if(count>0 && changes==0) {
- break;
- }
- changes=0;
- for(i=0;i<nBound;i++) {
- changes+=SegmentSet_BuildFaceEdgeCache_ExpandRight(pSet,i,1);
- }
- }
- /* On the second pass include backfaces for real panels */
- for(count=0;count<nBound;count++) {
- if(count>0 && changes==0) {
- break;
- }
- changes=0;
- for(i=0;i<nBound;i++) {
- changes+=SegmentSet_BuildFaceEdgeCache_ExpandRight(pSet,i,2);
- }
- }
- }
- /*
- ** This widget translates 3-D coordinates onto a flat canvas by splitting
- ** the 3-D space into layers and stacking the layers on the canvas.
- **
- ** The layers are decks of the ship. The highest layer (or deck) is drawn
- ** at the top of the page. The next layer down is drawn below the top layer.
- ** and so forth down the canvas. In other words, the 3D object is drawn
- ** by showing a set of 2D slices where each slice is viewed from above.
- **
- ** The original 3D coordinates are called "actual" coordinates. When
- ** translated into the 2D canvas they are called "canvas" coordinates.
- **
- ** The actual coordinate system is right-handed. The X axis increases to
- ** the right. The Y axis increases going up. The Z axis comes out of the
- ** page at the viewer. The canvas coordinate system is left-handed. The
- ** X axis increase to the right but the Y axis increases going down.
- **
- ** A plotter is a object with methods. The details of the available
- ** methods and what each does are described in comments before the
- ** implementation of each method.
- */
- /* Plotter_Delete */
- static void Plotter_Delete(ClientData clientData){
- /*
- ** This routine is called when a plotter is deleted. All the memory and
- ** other resources allocated by this plotter is recovered.
- */
- Plotter *p = (Plotter*)clientData;
- Odie_Free((char *)p);
- }
- /* Plotter_Clone */
- static int Plotter_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- ){
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("PLOTTERs are not clonable", -1));
- /* For now... */
- return TCL_ERROR;
- }
- /* Plotter_xCanvasToActual */
- static inline double Plotter_xCanvasToActual(Plotter *p,double cx){
- return (cx+p->rXOffset)*p->rZoom;
- }
- /* Plotter_yCanvasToActual */
- static inline double Plotter_yCanvasToActual(Plotter *p,double cy){
- return -1.0*(cy+p->rYOffset)*p->rZoom;
- }
- /* Plotter_xActualToCanvas */
- static inline double Plotter_xActualToCanvas(Plotter *p,double ax){
- /*
- ** Convert a Y coordinate from actual to canvas coordinates for a
- ** given deck.
- */
- return (ax/p->rZoom)-p->rXOffset;
- }
- /* Plotter_yActualToCanvas */
- static inline double Plotter_yActualToCanvas(Plotter *p,double ay){
- /*
- ** Convert a Y coordinate from actual to canvas coordinates for a
- ** given deck.
- */
- return -1.0*(ay/p->rZoom)-p->rYOffset;
- }
- /*
- ** This widget translates 3-D coordinates onto a flat canvas by splitting
- ** the 3-D space into layers and stacking the layers on the canvas.
- **
- ** The layers are decks of the ship. The highest layer (or deck) is drawn
- ** at the top of the page. The next layer down is drawn below the top layer.
- ** and so forth down the canvas. In other words, the 3D object is drawn
- ** by showing a set of 2D slices where each slice is viewed from above.
- **
- ** The original 3D coordinates are called "actual" coordinates. When
- ** translated into the 2D canvas they are called "canvas" coordinates.
- **
- ** The actual coordinate system is right-handed. The X axis increases to
- ** the right. The Y axis increases going up. The Z axis comes out of the
- ** page at the viewer. The canvas coordinate system is left-handed. The
- ** X axis increase to the right but the Y axis increases going down.
- **
- ** A slicer is a object with methods. The details of the available
- ** methods and what each does are described in comments before the
- ** implementation of each method.
- */
- /* Slicer_Delete */
- static void Slicer_Delete(ClientData clientData){
- /*
- ** This routine is called when a slicer is deleted. All the memory and
- ** other resources allocated by this slicer is recovered.
- */
- Slicer *p = (Slicer*)clientData;
- int i;
- for(i=0; i<p->nSlice; i++){
- Odie_Free((char *)p->a[i].zName);
- Odie_Free((char *)p->a[i].xz);
- }
- Odie_Free((char *)p->a);
- Odie_Free((char *)p);
- }
- /* Slicer_Clone */
- static int Slicer_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- ){
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("SLICERs are not clonable", -1));
- /* For now... */
- return TCL_ERROR;
- }
- /* Slicer_xCanvasToActual */
- static double Slicer_xCanvasToActual(Slicer *p,struct OneSlice *pS, double cx){
- double ax;
- if(p->nSlice==1) {
- ax = cx*p->rZoom;
- } else {
- ax = cx*p->rZoom - pS->rXShift;
- }
- return ax;
- }
- /* Slicer_yCanvasToActual */
- static double Slicer_yCanvasToActual(Slicer *p,struct OneSlice *pS, double cy){
- double ay;
- if(p->nSlice==1) {
- ay=-cy*p->rZoom;
- } else {
- ay = pS->mxY + (pS->mnY-pS->mxY)*(cy-pS->top)/(pS->btm-pS->top);
- }
- return ay;
- }
- /* Slicer_xActualToCanvas */
- static double Slicer_xActualToCanvas(Slicer *p,struct OneSlice *pS, double ax){
- /*
- ** Convert a X coordinate from actual to canvas coordinates for a
- ** given deck.
- */
- double cx;
- if(p->nSlice==1) {
- cx = ax/p->rZoom;
- } else {
- cx = (ax+pS->rXShift)/p->rZoom;
- }
- return cx;
- }
- /* Slicer_yActualToCanvas */
- static double Slicer_yActualToCanvas(Slicer *p,struct OneSlice *pS, double ay){
- /*
- ** Convert a Y coordinate from actual to canvas coordinates for a
- ** given deck.
- */
- double cy;
- if(p->nSlice==1) {
- cy=-ay/p->rZoom;
- } else {
- cy = pS->top + (pS->btm-pS->top)*(ay-pS->mxY)/(pS->mnY-pS->mxY);
- }
- return cy;
- }
- /* Slicer_deckHeight */
- static double Slicer_deckHeight(struct OneSlice *p, double rX){
- /*
- ** Return the height above baseline for the deck location rX.
- */
- int i;
- double *xz;
- if(!p) {
- return 0.0;
- }
- if( p->nXZ<4 ){
- return p->z;
- }
- xz = p->xz;
- if( rX<=xz[0] ){
- return xz[1];
- }
- for(i=2; i<p->nXZ; i+=2){
- if( rX<=xz[i] ){
- assert( xz[i]>xz[i-2] );
- return xz[i-1] + (xz[i+1]-xz[i-1])*(rX-xz[i-2])/(xz[i]-xz[i-2]);
- }
- }
- return xz[p->nXZ-1];
- }
- /* *Slicer_deckAt */
- static struct OneSlice *Slicer_deckAt(Slicer *p, double rX, double rZ){
- /*
- ** Return a pointer to the particular deck at actual coordinates
- ** X, Z
- */
- int i;
- struct OneSlice *pBest;
- double bestHeight;
- if( p->nSlice==0 ) return 0;
- pBest = &p->a[0];
- bestHeight = Slicer_deckHeight(pBest, rX);
- for(i=1; i<p->nSlice; i++){
- double dh = Slicer_deckHeight(&p->a[i],rX);
- if( dh>bestHeight && dh<=rZ ){
- pBest = &p->a[i];
- bestHeight = dh;
- }
- }
- return pBest;
- }
- /* *Slicer_deckAbove */
- static struct OneSlice *Slicer_deckAbove(Slicer *p, struct OneSlice *pRef){
- /*
- ** Return a pointer to the deck immediately above the given deck.
- ** Return NULL if the given deck is topmost.
- */
- int i;
- struct OneSlice *pBest = 0;
- if( p->nSlice==0 ) return 0;
- for(i=0; i<p->nSlice; i++){
- struct OneSlice *pTest = &p->a[i];
- if( pTest->z<=pRef->z ) continue;
- if( pBest==0 || pBest->z>pTest->z ){
- pBest = pTest;
- }
- }
- return pBest;
- }
- /* *Slicer_deckBelow */
- static struct OneSlice *Slicer_deckBelow(Slicer *p, struct OneSlice *pRef){
- /*
- ** Return a pointer to the deck immediately above the given deck.
- ** Return NULL if the given deck is topmost.
- */
- int i;
- struct OneSlice *pBest = 0;
- if( p->nSlice==0 ) return 0;
- for(i=0; i<p->nSlice; i++){
- struct OneSlice *pTest = &p->a[i];
- if( pTest->z>=pRef->z ) continue;
- if( pBest==0 || pBest->z<pTest->z ){
- pBest = pTest;
- }
- }
- return pBest;
- }
- /* Slicer_computeTopAndBottom */
- static void Slicer_computeTopAndBottom(Slicer *p){
- /*
- ** Recompute the values of p->a[].top and p->a[].btm for all slices in
- ** the given slicer.
- */
- int i;
- double rY = 0.0;
- double rBound = -9.9e99;
- for(i=p->nSlice-1; i>=0; i--){
- double h = (p->a[i].mxY - p->a[i].mnY)/p->rZoom;
- p->a[i].upperbound = rBound;
- p->a[i].top = rY;
- p->a[i].btm = rY + h;
- rY = p->a[i].btm + 0.3*h;
- rBound = p->a[i].btm + 0.15*h;
- }
- if( p->nSlice==0 ) return;
- /* Calculate the above and below for each deck */
- for(i=0; i<p->nSlice; i++){
- struct OneSlice *pThis = &p->a[i];
- struct OneSlice *pBest = 0;
- pBest=Slicer_deckAbove(p,pThis);
- if(pBest) {
- pThis->above=pBest->did;
- } else {
- pThis->above=0;
- }
- pBest=Slicer_deckBelow(p,pThis);
- if(pBest) {
- pThis->below=pBest->did;
- } else {
- pThis->below=0;
- }
- }
- }
- /* Slicer_getDeck */
- static int Slicer_getDeck(
- Tcl_Interp *interp, /* Put error messages here */
- Slicer *p, /* The slicer */
- double rX, /* X coord used to find deck if pObj is a Z coord */
- Tcl_Obj *pObj, /* Either a deck name or a Z coordinate */
- struct OneSlice **ppS /* Write the slice pointer here */
- ){
- /*
- ** pObj is either the name of a deck or a Z coordinate. If it is a
- ** deck name, find the deck and write a pointer to it in *ppS. If
- ** it is a Z coordinate, use that coordinate together with rX to
- ** find the deck and write it into *ppS. If an error occurs, put
- ** an error message on the TCL interpreter and return TCL_ERROR.
- ** Return TCL_OK on success.
- */
- double rZ;
- const char *zName;
- int i;
- if(p->nSlice==1) {
- *ppS=&p->a[0];
- return TCL_OK;
- }
- if( Tcl_GetDoubleFromObj(0, pObj, &rZ)==TCL_OK ){
- *ppS = Slicer_deckAt(p, rX, rZ);
- return TCL_OK;
- }
- zName = Tcl_GetStringFromObj(pObj, 0);
- for(i=0; i<p->nSlice; i++){
- if( strcmp(zName, p->a[i].zName)==0 ){
- *ppS = &p->a[i];
- return TCL_OK;
- }
- }
- Tcl_AppendResult(interp, "no such deck: ", zName, 0);
- return TCL_ERROR;
- }
- /* Slicer_getDeckId */
- static int Slicer_getDeckId(
- Tcl_Interp *interp, /* Put error messages here */
- Slicer *p, /* The slicer */
- Tcl_Obj *pObj, /* Either a deck name or a Z coordinate */
- struct OneSlice **ppS /* Write the slice pointer here */
- ){
- /*
- ** pObj is either the name of a deck or a Z coordinate. If it is a
- ** deck name, find the deck and write a pointer to it in *ppS. If
- ** it is a Z coordinate, use that coordinate together with rX to
- ** find the deck and write it into *ppS. If an error occurs, put
- ** an error message on the TCL interpreter and return TCL_ERROR.
- ** Return TCL_OK on success.
- */
- int did;
- const char *zName;
- int i;
- if(p->nSlice==1) {
- *ppS=&p->a[0];
- return TCL_OK;
- }
- if( Tcl_GetIntFromObj(interp, pObj, &did)==TCL_OK ){
- for(i=0; i<p->nSlice; i++){
- if( did == p->a[i].did ){
- *ppS = &p->a[i];
- return TCL_OK;
- }
- }
- Tcl_AppendResult(interp, "no such deckid: ", 0);
- return TCL_ERROR;
- }
- zName = Tcl_GetStringFromObj(pObj, 0);
- for(i=0; i<p->nSlice; i++){
- if( strcmp(zName, p->a[i].zName)==0 ){
- *ppS = &p->a[i];
- return TCL_OK;
- }
- }
- Tcl_AppendResult(interp, "no such deck: ", zName, 0);
- return TCL_ERROR;
- }
- /* *Slicer_GetSlicerFromObj */
- Slicer *Slicer_GetSlicerFromObj(Tcl_Interp *interp,Tcl_Obj *tclobj){
- Tcl_Object pObj;
- Slicer *pSlicer=NULL;
- pObj=Tcl_GetObjectFromObj(interp,tclobj);
- if(!pObj) {
- return NULL;
- }
- pSlicer=(Slicer *)Tcl_ObjectGetMetadata(pObj,&SlicerDataType);
- return pSlicer;
- }
- /* *Slicer_getDeck_FromInt */
- static inline struct OneSlice *Slicer_getDeck_FromInt(
- Slicer *p,
- int did
- ){
- int i;
- if(p->nSlice==1) {
- return &p->a[0];
- }
- for(i=0; i<p->nSlice; i++){
- if( did == p->a[i].did ){
- return &p->a[i];
- }
- }
- return NULL;
- }
- /* slicer_drawline_do */
- static int slicer_drawline_do(
- Tcl_Interp *interp,
- Slicer *p,
- int coord_count,
- int *deckCoord,double *xCoord,double *yCoord,
- struct OneSlice **apDeck,
- Tcl_Obj *canvas,
- const char *zKTag,
- const char *zXTag,
- const char *zBTag
- ){
- int i;
- Tcl_Obj *pVTag; /* The "sNNN" tag added to all line segments */
- Tcl_Obj *aLineArg[20]; /* Element of "create line" TCL command */
- int nLineArg; /* Number of used entries in aLineArg[] */
- Tcl_Obj *aBendArg[20]; /* Cmd to bends penetractions */
- int nBendArg;
- nBendArg = 0;
- if(zBTag) {
- aBendArg[0] = canvas;
- aBendArg[1] = ODIE_CONSTANT_STRING("create");
- aBendArg[2] = ODIE_CONSTANT_STRING("oval");
- for(i=3; i<=6; i++){
- aBendArg[i] = Tcl_NewObj();
- }
- aBendArg[7] = ODIE_CONSTANT_STRING("-tags");
- for(i=0; i<=7; i++){
- Tcl_IncrRefCount(aBendArg[i]);
- }
- nBendArg = 9;
- }
- aLineArg[0] = canvas;
- aLineArg[1] = ODIE_CONSTANT_STRING("create");
- aLineArg[2] = ODIE_CONSTANT_STRING("line");
- for(i=3; i<=6; i++){
- aLineArg[i] = Tcl_NewObj();
- }
- aLineArg[7] = ODIE_CONSTANT_STRING("-tags");
- for(i=0; i<=7; i++){
- Tcl_IncrRefCount(aLineArg[i]);
- }
- nLineArg = 9;
- for(i=1; i<coord_count; i++){
- char zBuf[30];
- double x0, y0, x1, y1;
- x0 = Slicer_xActualToCanvas(p,apDeck[i-1],xCoord[i-1]);
- x1 = Slicer_xActualToCanvas(p,apDeck[i],xCoord[i]);
- y0 = Slicer_yActualToCanvas(p,apDeck[i-1],yCoord[i-1]);
- y1 = Slicer_yActualToCanvas(p,apDeck[i], yCoord[i]);
- Tcl_SetDoubleObj(aLineArg[3], x0);
- Tcl_SetDoubleObj(aLineArg[4], y0);
- Tcl_SetDoubleObj(aLineArg[5], x1);
- Tcl_SetDoubleObj(aLineArg[6], y1);
- if( apDeck[i]!=apDeck[i-1] && zXTag ){
- sprintf(zBuf, "%s s%d", zXTag, i);
- } else {
- sprintf(zBuf, "%s s%d", zKTag, i);
- }
- pVTag = Tcl_NewStringObj(zBuf, -1);
- Tcl_IncrRefCount(pVTag);
- aLineArg[8]=pVTag;
- if(i<(coord_count-1) && nBendArg) {
- char bBuf[30];
- Tcl_Obj *pBTag; /* The "nNNN" tag added to all line bend points */
- sprintf(bBuf, "%s b%d", zBTag, i);
- pBTag = Tcl_NewStringObj(bBuf, -1);
- Tcl_IncrRefCount(pVTag);
- Tcl_SetDoubleObj(aBendArg[3], x1-4);
- Tcl_SetDoubleObj(aBendArg[4], y1-4);
- Tcl_SetDoubleObj(aBendArg[5], x1+4);
- Tcl_SetDoubleObj(aBendArg[6], y1+4);
- aBendArg[8] = pBTag;
- Tcl_EvalObjv(interp, nBendArg, aBendArg, 0);
- }
- Tcl_EvalObjv(interp, nLineArg, aLineArg, 0);
- }
- for(i=0; i<=7; i++){
- Tcl_DecrRefCount(aLineArg[i]);
- if( i<nBendArg ) Tcl_DecrRefCount(aBendArg[i]);
- }
- for(i=9; i<nLineArg; i++){
- Tcl_DecrRefCount(aLineArg[i]);
- }
- for(i=9; i<nBendArg; i++){
- Tcl_DecrRefCount(aBendArg[i]);
- }
- return TCL_OK;
- }
- /* Slicer_Location_zabs */
- static inline double Slicer_Location_zabs(Slicer *p,struct OneSlice *pS,double x0,double dheight){
- struct OneSlice *pAbove;
- if(dheight >= 0) {
- return dheight+Slicer_deckHeight(pS,x0);
- }
- pAbove=Slicer_deckAbove(p,pS);
- if(pAbove) {
- return Slicer_deckHeight(pAbove,x0)+dheight;
- }
- return Slicer_deckHeight(pS,x0)+p->upper_height+dheight;
- }
- /* Location_zdeck */
- static inline double Location_zdeck(Slicer *p,struct OneSlice *pS,double x0,double dheight){
- struct OneSlice *pAbove;
- if(dheight >= 0) {
- return dheight;
- }
- pAbove=Slicer_deckAbove(p,pS);
- if(pAbove) {
- return Slicer_deckHeight(pAbove,x0)-Slicer_deckHeight(pS,x0)+dheight;
- }
- return p->upper_height+dheight;
- }
- /* Slicer_Find_Deckid_And_Offset */
- int Slicer_Find_Deckid_And_Offset(Slicer *pSlicer,double x0,double y0,double z0,int *deckid,double *zoff){
- struct OneSlice *ppS,*pAbove;
- double zdeck;
- *zoff=0.0;
- *deckid=0;
- if(!pSlicer) {
- return TCL_ERROR;
- }
- ppS=Slicer_deckAt(pSlicer,x0,z0);
- if(!ppS) {
- return TCL_ERROR;
- }
- *deckid=ppS->did;
- zdeck=Slicer_deckHeight(ppS,x0);
- *zoff=z0-zdeck;
- return TCL_OK;
- }
- /* Slicer_Absolute_Z */
- double Slicer_Absolute_Z(Slicer *pSlicer,int deckid,double x0,double y0,double zoff){
- struct OneSlice *ppS,*pAbove;
- double zresult=0.0;
- if(!pSlicer) {
- return 0;
- }
- ppS=Slicer_getDeck_FromInt(pSlicer,deckid);
- if(!ppS) {
- return 0;
- }
- if(zoff < 0.0) {
- pAbove = Slicer_deckAbove(pSlicer, ppS);
- if(pAbove) {
- zresult=Slicer_deckHeight(pAbove,x0)+zoff;
- } else {
- zresult=Slicer_deckHeight(ppS,x0)+2000+zoff;
- }
- } else {
- zresult=Slicer_deckHeight(ppS,x0)+zoff;
- }
- return zresult;
- }
- /*
- ** This file implements a TCL object that keeps track of the walls and
- ** bulkheads on a single deck of a ship.
- **
- ** This widget assumes a right-handed coordinate system if zoom is positive
- ** and a left-handed coordinate system is zoom is negative. The Tk canvas
- ** widget uses a left-handed coordinate system all the time. The READI
- ** database uses a right-handed coordinate system all the time. This module
- ** can be used to translate by setting zoom to +1.0 for database I/O and
- ** to -$g(zoom) for canvas I/O.
- **
- ** This module uses a purely 2-D model. It can only handle a single
- ** deck at a time. If a multi-deck model needs to be displayed then
- ** that multi-deck model should first be flattened into a stack of
- ** individual decks in the same plane using the separate "slicer" object.
- **
- ** This file implements a single new constructor tcl command named "wallset".
- ** The wallset command creates a new wallset object. Methods on this
- ** wallset object are used to manage the object.
- **
- ** The details of the various methods and what they do are provided in
- ** header comments above the implementation of each method.
- */
- #ifndef M_PI
- # define M_PI 3.1415926535898
- #endif
- /*
- ** Remove all of the ComptBox entries from the wallset.
- */
- static void clearComptBoxCache(Wallset *pWS){
- ComptBox *p = pWS->pComptBox;
- while( p ){
- ComptBox *pNext = p->pNext;
- Tcl_Free((char *)p);
- p = pNext;
- }
- pWS->pComptBox = 0;
- }
- /*
- ** This routine is invoked when the TCL command that implements a
- ** wallset is deleted. Free all memory associated with that
- ** wallset.
- */
- static void destroyWallset(void *pArg){
- Wallset *p = (Wallset*)pArg;
- Link *pLink = p->pAll;
- clearComptBoxCache(p);
- while( pLink ){
- Segment *pSeg = pLink->pLinkNode;
- pLink = pSeg->pAll.pNext;
- Tcl_Free((char *) pSeg );
- }
- Tcl_Free((char *) p );
- }
- /*
- ** Clear the Segment.ignore flag on all segments within a wallset.
- */
- static void ignoreNone(Wallset *p){
- #if 0
- Link *pLink;
- for(pLink=p->pAll; pLink; pLink=pLink->pNext){
- pLink->pSeg->ignore = 0;
- }
- #endif
- }
- /*
- ** Return a pointer to the segment with the given ID. Return NULL
- ** if there is no such segment.
- */
- static Segment *findSegment(Wallset *p, int id){
- int h;
- Link *pLink;
- h = hashInt(id);
- for(pLink = p->hashId[h]; pLink; pLink=pLink->pNext){
- Segment *pSeg=pLink->pLinkNode;
- if( pSeg->id==id ) return pSeg;
- }
- return 0;
- }
- /*
- ** Scan all segments looking for the vertex or vertices that are nearest
- ** to x,y. Return a pointer to a Segment.set that is the list of matching
- ** segments. Also write the nearest point into *pX,*pY.
- **
- ** The returned list uses the Segment.set link.
- */
- static Link *nearestVertex(
- Wallset *p, /* The wallset to be scanned */
- double x, double y, /* Search for points near to this point */
- double *pX, double *pY /* Write nearest vertex here */
- ){
- double nx, ny;
- double min = -1.0;
- Link *pList = 0;
- Link *pI;
- nx = x = roundCoord(x);
- ny = y = roundCoord(y);
- for(pI=p->pAll; pI; pI=pI->pNext){
- double dx, dy, dist;
- Segment *pSeg = pI->pLinkNode;
- dx = x - pSeg->from[X_IDX];
- dy = y - pSeg->from[Y_IDX];
- dist = dx*dx + dy*dy;
- if( min<0.0 || dist<=min ){
- if( min<0.0 || nx!=pSeg->from[X_IDX] || ny!=pSeg->from[Y_IDX] ){
- pList = 0;
- nx = pSeg->from[X_IDX];
- ny = pSeg->from[Y_IDX];
- min = dist;
- }
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- dx = x - pSeg->to[X_IDX];
- dy = y - pSeg->to[Y_IDX];
- dist = dx*dx + dy*dy;
- if( dist<=min ){
- if( nx!=pSeg->to[X_IDX] || ny!=pSeg->to[Y_IDX] ){
- pList = 0;
- nx = pSeg->to[X_IDX];
- ny = pSeg->to[Y_IDX];
- min = dist;
- }
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- }
- *pX = nx;
- *pY = ny;
- return pList;
- }
- /*
- ** Scan all segments looking for the point on a segment that is nearest
- ** to x,y. Return a pointer to a Segment.set that is the list of matching
- ** segments. This set might contain multiple members if the nearest point
- ** is actually a vertex shared by two or more segments. Write the nearest
- ** point into *pX, *pY.
- **
- ** /// Ignore any segment that has its Segment.ignore flag set. -- removed
- **
- ** The returned list uses the Segment.set list.
- */
- static Link *nearestPoint(
- Wallset *p, /* The wallset to be scanned */
- double x, double y, /* Search for points near to this point */
- double *pX, double *pY /* Write nearest vertex here */
- ){
- double nx, ny;
- double min = -1.0;
- Link *pList = 0;
- Link *pI;
- nx = x = roundCoord(x);
- ny = y = roundCoord(y);
- for(pI=p->pAll; pI; pI=pI->pNext){
- double dx, dy, dist;
- Segment *pSeg;
- double acx, acy; /* Vector from x0,y0 to x,y */
- double abx, aby; /* Vector from x0,y0 to x1,y1 */
- double rx, ry; /* Nearest point on x0,y0->to[X_IDX],y1 to x,y */
- double r;
- pSeg = pI->pLinkNode;
- /* if( pSeg->ignore ) continue; */
- acx = x - pSeg->from[X_IDX];
- acy = y - pSeg->from[Y_IDX];
- abx = pSeg->to[X_IDX] - pSeg->from[X_IDX];
- aby = pSeg->to[Y_IDX] - pSeg->from[Y_IDX];
- r = (acx*abx + acy*aby)/(abx*abx + aby*aby);
- if( r<=0 ){
- rx = pSeg->from[X_IDX];
- ry = pSeg->from[Y_IDX];
- }else if( r>=1 ){
- rx = pSeg->to[X_IDX];
- ry = pSeg->to[Y_IDX];
- }else{
- rx = pSeg->from[X_IDX] + abx*r;
- ry = pSeg->from[Y_IDX] + aby*r;
- }
- rx = roundCoord(rx);
- ry = roundCoord(ry);
- dx = x - rx;
- dy = y - ry;
- dist = dx*dx + dy*dy;
- if( min<0.0 || dist<=min ){
- if( min<0.0 || nx!=rx || ny!=ry ){
- pList = 0;
- nx = rx;
- ny = ry;
- min = dist;
- }
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- }
- *pX = nx;
- *pY = ny;
- return pList;
- }
- /*
- ** Return TRUE if the value x is in between x1 and x2.
- */
- static int between(double x, double x1, double x2){
- if( x1<x2 ){
- return x>=x1 && x<=x2;
- }else{
- return x>=x2 && x<=x1;
- }
- }
- /*
- ** Return TRUE if the given segment is on the given list
- */
- static int segmentOnList(Segment *pSeg, Link *pList){
- while( pList ){
- if( pList->pLinkNode==pSeg ) return 1;
- pList = pList->pNext;
- }
- return 0;
- }
- /*
- ** Return a list of all segments which have an end at the given vertex.
- ** The returned list uses Segment.set
- */
- static Link *segmentsAtVertex(Wallset *p, double x, double y){
- Link *pList = 0;
- Link *pI;
- int h;
- x = roundCoord(x);
- y = roundCoord(y);
- h = hashCoord(x, y);
- for(pI=p->hashFrom[h]; pI; pI=pI->pNext){
- Segment *pSeg = pI->pLinkNode;
- /* if( pSeg->ignore ) continue; */
- if( floatCompare(x, pSeg->from[X_IDX])==0 && floatCompare(y, pSeg->from[Y_IDX])==0 ){
- assert( !segmentOnList(pSeg, pList) );
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- }
- for(pI=p->hashTo[h]; pI; pI=pI->pNext){
- Segment *pSeg = pI->pLinkNode;
- /* if( pSeg->ignore ) continue; */
- if( floatCompare(x, pSeg->to[X_IDX])==0 && floatCompare(y, pSeg->to[Y_IDX])==0 ){
- assert( !segmentOnList(pSeg, pList) );
- LinkInit(pSeg->pSet, pSeg);
- LinkInsert(&pList, &pSeg->pSet);
- }
- }
- return pList;
- }
- /*
- ** The point xV,yV is a vertex in the wallset. This routine locates
- ** a segment connected to that vertex which is the first segment in
- ** a clockwise direction from xR,yR->xV,yV. A pointer to the segment
- ** is written into *ppSeg. If the output segment moves backwards
- ** (in other words if x1,y1 of the segment is connected at xV,yV)
- ** then *pfBack is true.
- **
- ** If a suitable segment is found, 0 is returned. Non-zero is returned
- ** if no suitable segment could be found.
- **
- ** This routine uses the Segment.set list internally.
- */
- static int nextCwSegment(
- Wallset *p, /* The wallset */
- double xR, double yR, /* Remote end of input segment */
- double xV, double yV, /* Vertex (near end of input segment) */
- Segment **ppSeg, /* OUT: First segment clockwise from xR,yR->xV,yV */
- int *pfBack /* OUT: True if output segment goes backwards */
- ){
- Link *pList, *pI;
- double rRef, rBest;
- int i, nSeg, iBest;
- Segment *pSeg;
- struct {
- Segment *pSeg;
- int isBack;
- double rAngle;
- } *aSeg, aSegStatic[20];
- /* Find all segments at xV,yV */
- pList = segmentsAtVertex(p, xV, yV);
- for(pI=pList, nSeg=0; pI; nSeg++, pI=pI->pNext){}
- if( nSeg==0 ) return 1;
- if( nSeg<=sizeof(aSegStatic)/sizeof(aSegStatic[0]) ){
- aSeg = aSegStatic;
- }else{
- aSeg = (void *)Odie_Alloc( nSeg*sizeof(*aSeg) );
- }
- for(pI=pList, i=0; pI; i++, pI=pI->pNext){
- aSeg[i].pSeg = pSeg = pI->pLinkNode;
- aSeg[i].isBack = floatCompare(xV, pSeg->to[X_IDX])==0
- && floatCompare(yV, pSeg->to[Y_IDX])==0;
- }
- /* Find the reference angle */
- rRef = atan2(yR-yV, xR-xV)*180.0/M_PI;
- /* Find angles on all segments */
- for(i=0; i<nSeg; i++){
- pSeg = aSeg[i].pSeg;
- if( aSeg[i].isBack ){
- aSeg[i].rAngle = atan2(pSeg->from[Y_IDX]-pSeg->to[Y_IDX], pSeg->from[X_IDX]-pSeg->to[X_IDX])*180.0/M_PI;
- }else{
- aSeg[i].rAngle = atan2(pSeg->to[Y_IDX]-pSeg->from[Y_IDX], pSeg->to[X_IDX]-pSeg->from[X_IDX])*180.0/M_PI;
- }
- }
- /* Subtract 360 to any segment angle that is less than the reference angle */
- for(i=0; i<nSeg; i++){
- if( aSeg[i].rAngle<rRef ) aSeg[i].rAngle += 360;
- }
- /* Choose the segment with the largest angle */
- rBest = aSeg[0].rAngle;
- iBest = 0;
- for(i=1; i<nSeg; i++){
- if( aSeg[i].rAngle>rBest ){
- iBest = i;
- rBest = aSeg[i].rAngle;
- }
- }
- *ppSeg = aSeg[iBest].pSeg;
- *pfBack = aSeg[iBest].isBack;
- if( aSeg!=aSegStatic ){
- Tcl_Free((char *) aSeg );
- }
- return 0;
- }
- /*
- ** Consider a line beginning at x0,y0 then going from x1,y1 to x2,y2.
- ** x1,y1 is an elbow in the line. This routine returns -1 if the
- ** elbow bends to the right, and +1 if it bends to the left. zero is
- ** returned if the elbow does not bend at all.
- */
- static int bendDirection(
- double x0, double y0,
- double x1, double y1,
- double x2, double y2
- ){
- /* Algorithm: Rotate x0,y0->to[X_IDX],y1 90 degrees counter-clockwise. Take
- ** the dot product with x1,y1->x2,y2. The dot produce will be the product
- ** of two (non-negative) magnitudes and the cosine of the angle. So if
- ** the dot product is positive, the bend is to the left, or to the right if
- ** the dot product is negative.
- */
- double r = (y0-y1)*(x2-x1) + (x1-x0)*(y2-y1);
- return r<0.0 ? +1 : (r>0.0 ? -1 : 0);
- }
- /*
- ** Given an interior point xI,yI, this routine finds a segment on the
- ** boundary that contains the interior point. That segment is returned
- ** in *ppSeg. *pfLeft is set to true if the interior point is to the left
- ** of the segment and false if it is to the right.
- **
- ** Zero is returned on success. Non-zero is returned if no suitable
- ** boundary could be located. Non-zero might be returned, for example,
- ** if xI,yI is positioned directly on top of a wall or if there are no
- ** walls in the wallset.
- **
- ** // Any segment marked with Segment.ignore is ignored for purposes of
- ** // this routine. -- removed
- **
- ** This routine uses the Segment.set list internally.
- */
- static int firstBoundarySegment(
- Wallset *p, /* The wallset */
- double xI, double yI, /* An interior point */
- Segment **ppSeg, /* OUT: A segment on the boundary containing xI,yI */
- int *pfLeft /* OUT: True if xI,yI is to the left side *ppSeg */
- ){
- Link *pList;
- double xN, yN;
- /* Find nearest point, xN,yN */
- pList = nearestPoint(p, xI, yI, &xN, &yN);
- if( pList==0 ) return 1;
- if( pList->pNext ){
- /* xN,yN is a vertex...
- ** Locate the first segment clockwise from xI,yI->xN,yN and return
- */
- return nextCwSegment(p, xI, yI, xN, yN, ppSeg, pfLeft);
- }else{
- /* xN,yN is a point on single line segment...
- */
- Segment *pSeg;
- pSeg = *ppSeg = pList->pLinkNode;
- *pfLeft = bendDirection(pSeg->from[X_IDX], pSeg->from[Y_IDX], xN, yN, xI, yI)>0;
- }
- return 0;
- }
- /*
- ** Fill the given Boundary array with a list of segments (with
- ** Segment.ignore set to false) that form a closed circuit. The
- ** first entry in aBound[] has already been filled in by the
- ** calling function and is used to seed the search.
- **
- ** At most nBound slots in aBound[] will be used. The return value
- ** is the number of slots in aBound[] that would have been used if those
- ** slots had been available. A return of 0 indicates that no boundary
- ** is available.
- **
- ** If the checkIsPrimary flag is true and the aBound[0] entry is not
- ** the primary segment for the compartment, then the aBound[] is not
- ** completely filled in and the routine returns 0;
- */
- static int completeBoundary(
- Wallset *p, /* The wallset */
- int checkIsPrimary, /* Abort if aBound[0] is not the primary segment */
- int nBound, /* Number of slots available in aBound[] */
- Boundary *aBound /* IN-OUT: Write results into aBound[1...] */
- ){
- int cnt = 1;
- Segment *pSeg, *pS;
- int isLeft;
- int isBack;
- double xR, yR, xV, yV;
- pS = pSeg = aBound[0].pSeg;
- isLeft = aBound[0].backwards;
- if( !isLeft ){
- xR = pSeg->from[X_IDX];
- yR = pSeg->from[Y_IDX];
- xV = pSeg->to[X_IDX];
- yV = pSeg->to[Y_IDX];
- }else{
- xV = pSeg->from[X_IDX];
- yV = pSeg->from[Y_IDX];
- xR = pSeg->to[X_IDX];
- yR = pSeg->to[Y_IDX];
- }
- while( nextCwSegment(p,xR,yR,xV,yV,&pS,&isBack)==0 &&
- (isBack!=isLeft || pS!=pSeg) ){
- if( checkIsPrimary ){
- if( pS->id<pSeg->id ) return 0;
- if( pS->id==pSeg->id && !isLeft ) return 0;
- }
- if( isBack ){
- xV = pS->from[X_IDX];
- yV = pS->from[Y_IDX];
- xR = pS->to[X_IDX];
- yR = pS->to[Y_IDX];
- }else{
- xR = pS->from[X_IDX];
- yR = pS->from[Y_IDX];
- xV = pS->to[X_IDX];
- yV = pS->to[Y_IDX];
- }
- if( nBound>cnt ){
- aBound[cnt].pSeg = pS;
- aBound[cnt].backwards = isBack;
- }
- cnt++;
- if( cnt>1000 /* 00 */ ) return -cnt; /* Avoid an infinite loop */
- }
- return cnt;
- }
- /*
- ** Compute the "spin" on a boundary. A positive value means the
- ** circulation is to counter-clockwise and a negative value means the
- ** circulation is clockwise. For boundaries, a positive
- ** value means the region is internal and a negative value means
- ** the region is external.
- */
- static double spin(Boundary *aBound, int nBound){
- double sum = 0;
- int i;
- for(i=0; i<nBound; i++){
- double x0, y0, x1, y1;
- double dx, dy;
- Segment *pSeg = aBound->pSeg;
- if( aBound->backwards ){
- x0 = pSeg->to[X_IDX];
- y0 = pSeg->to[Y_IDX];
- x1 = pSeg->from[X_IDX];
- y1 = pSeg->from[Y_IDX];
- }else{
- x0 = pSeg->from[X_IDX];
- y0 = pSeg->from[Y_IDX];
- x1 = pSeg->to[X_IDX];
- y1 = pSeg->to[Y_IDX];
- }
- aBound++;
- dx = x1-x0;
- dy = y1-y0;
- sum += x0*dy - y0*dx;
- }
- return sum;
- }
- /*
- ** The input is two linked lists of ComptBox structures where each
- ** list is sorted by increasing area. Combine these two lists into
- ** a single sorted linked list.
- */
- static ComptBox *mergeComptBox(ComptBox *p1, ComptBox *p2){
- ComptBox head;
- ComptBox *pTail = &head;
- ComptBox *p;
- while( p1 && p2 ){
- if( p1->area<=p2->area ){
- p = p1->pNext;
- pTail->pNext = p1;
- pTail = p1;
- p1 = p;
- }else{
- p = p2->pNext;
- pTail->pNext = p2;
- pTail = p2;
- p2 = p;
- }
- }
- if( p1 ){
- pTail->pNext = p1;
- }else{
- pTail->pNext = p2;
- }
- return head.pNext;
- }
- /*
- ** Construct the ComptBox cache. For each compartment (where a compartment
- ** is a closed circuit of Segments) make an entry on the Wallset.pComptBox
- ** list.
- **
- ** If the ComptBox cache already exists, this routine is a no-op.
- */
- static void buildComptBoxCache(Wallset *p){
- Link *pI;
- int i;
- ComptBox *aSort[30];
- /* Return immediately if the cache already exists */
- if( p->pComptBox ) return;
- /* Compute a linked list of all compartment boxes */
- for(pI=p->pAll; pI; pI=pI->pNext){
- int i, j, n;
- Boundary aBound[1000];
- aBound[0].pSeg = pI->pLinkNode;
- for(j=0; j<2; j++){
- aBound[0].backwards = j;
- n = completeBoundary(p, 1, sizeof(aBound)/sizeof(aBound[0]), aBound);
- if( n>0 && spin(aBound,n)>0.0 ){
- double dx, dy;
- Segment *pSeg = pI->pLinkNode;
- ComptBox *pNew = (ComptBox *)Odie_Alloc( sizeof(*pNew) );
- pNew->pNext = p->pComptBox;
- pNew->bbox[BBOX_X0_IDX] = pNew->bbox[BBOX_X1_IDX] = pSeg->from[X_IDX];
- pNew->bbox[BBOX_Y1_IDX] = pNew->bbox[BBOX_Y0_IDX] = pSeg->from[Y_IDX];
- pNew->prim = aBound[0];
- for(i=1; i<n; i++){
- Segment *pSeg = aBound[i].pSeg;
- if( pSeg->from[X_IDX]<pNew->bbox[BBOX_X0_IDX] ) pNew->bbox[BBOX_X0_IDX] = pSeg->from[X_IDX];
- if( pSeg->from[X_IDX]>pNew->bbox[BBOX_X1_IDX] ) pNew->bbox[BBOX_X1_IDX] = pSeg->from[X_IDX];
- if( pSeg->from[Y_IDX]<pNew->bbox[BBOX_Y0_IDX] ) pNew->bbox[BBOX_Y0_IDX] = pSeg->from[Y_IDX];
- if( pSeg->from[Y_IDX]>pNew->bbox[BBOX_Y1_IDX] ) pNew->bbox[BBOX_Y1_IDX] = pSeg->from[Y_IDX];
- if( pSeg->to[X_IDX]<pNew->bbox[BBOX_X0_IDX] ) pNew->bbox[BBOX_X0_IDX] = pSeg->to[X_IDX];
- if( pSeg->to[X_IDX]>pNew->bbox[BBOX_X1_IDX] ) pNew->bbox[BBOX_X1_IDX] = pSeg->to[X_IDX];
- if( pSeg->to[Y_IDX]<pNew->bbox[BBOX_Y0_IDX] ) pNew->bbox[BBOX_Y0_IDX] = pSeg->to[Y_IDX];
- if( pSeg->to[Y_IDX]>pNew->bbox[BBOX_Y1_IDX] ) pNew->bbox[BBOX_Y1_IDX] = pSeg->to[Y_IDX];
- }
- dx = pNew->bbox[BBOX_X1_IDX] - pNew->bbox[BBOX_X0_IDX];
- dy = pNew->bbox[BBOX_Y1_IDX] - pNew->bbox[BBOX_Y0_IDX];
- pNew->area = sqrt(dx*dx+dy*dy);
- p->pComptBox = pNew;
- }
- }
- }
- /* Sort the list into order of increasing area */
- for(i=0; i<sizeof(aSort)/sizeof(aSort[0]); i++) aSort[i] = 0;
- while( p->pComptBox ){
- ComptBox *pBox = p->pComptBox;
- p->pComptBox = pBox->pNext;
- pBox->pNext = 0;
- for(i=0; i<sizeof(aSort)/sizeof(aSort[0])-1 && aSort[i]!=0; i++){
- pBox = mergeComptBox(aSort[i], pBox);
- aSort[i] = 0;
- }
- aSort[i] = mergeComptBox(aSort[i], pBox);
- }
- for(i=0; i<sizeof(aSort)/sizeof(aSort[0]); i++){
- p->pComptBox = mergeComptBox(aSort[i], p->pComptBox);
- }
- }
- /*
- ** Test to see if the point x,y is contained within the given
- ** boundary or is on the outside of the boundary.
- */
- static int pointWithinBoundary(
- Boundary *aBound, /* The boundary */
- int nBound, /* Number of segments in the boundary */
- double x, double y /* The point to test */
- ){
- int inside = 0;
- int i;
- for(i=0; i<nBound; i++){
- double x0, y0, x1, y1;
- Segment *p = aBound[i].pSeg;
- x0 = p->from[X_IDX];
- y0 = p->from[Y_IDX];
- x1 = p->to[X_IDX];
- y1 = p->to[Y_IDX];
- if( x0==x1 ) continue;
- if( (x0>x && x1>x) || (x0<x && x1<x) ) continue;
- if( y1 - (x1-x)*(y1-y0)/(x1-x0) >= y ) inside = !inside;
- }
- return inside;
- }
- /*
- ** Find a boundary which contains xI, yI. If the size of the boundary
- ** is set to 0, that means no such boundary exists.
- */
- static int findBoundary(
- Wallset *p, /* The wallset */
- double xI, double yI, /* A point that the boundary should be near */
- int nBound, /* Number of slots available in aBound[] */
- Boundary *aBound /* OUT: Write results here */
- ){
- int n = 0;
- ComptBox *pBox;
- buildComptBoxCache(p);
- for(pBox=p->pComptBox; pBox; pBox=pBox->pNext){
- if( xI<pBox->bbox[BBOX_X0_IDX] || xI>pBox->bbox[BBOX_X1_IDX] || yI<pBox->bbox[BBOX_Y0_IDX] || yI>pBox->bbox[BBOX_Y1_IDX] ) continue;
- aBound[0] = pBox->prim;
- n = completeBoundary(p, 0, nBound, aBound);
- if( n>0 && pointWithinBoundary(aBound, n, xI, yI) ) break;
- n = 0;
- }
- return n;
- }
- /*
- ** Do an check of the integrity of the internal data structures. If
- ** a problem is found, leave an error message in interp->result and
- ** return TCL_ERROR. Return TCL_OK if everything is OK.
- */
- static int selfCheck(Tcl_Interp *interp, Wallset *p){
- Link *pLink;
- Segment *pSeg;
- int h;
- char zErr[200];
- for(pLink=p->pAll; pLink; pLink=pLink->pNext){
- pSeg = pLink->pLinkNode;
- h = hashInt(pSeg->id);
- if(!segmentOnList(pSeg, p->hashId[h]) ){
- sprintf(zErr, "segment %d missing from hashId[%d]", pSeg->id, h);
- Tcl_SetResult(interp, zErr, TCL_VOLATILE);
- return TCL_ERROR;
- }
- h = hashCoord(pSeg->from[X_IDX], pSeg->from[Y_IDX]);
- if(!segmentOnList(pSeg, p->hashFrom[h]) ){
- sprintf(zErr, "segment %d missing from hashFrom[%d]", pSeg->id, h);
- Tcl_SetResult(interp, zErr, TCL_VOLATILE);
- return TCL_ERROR;
- }
- h = hashCoord(pSeg->to[X_IDX], pSeg->to[Y_IDX]);
- if(!segmentOnList(pSeg, p->hashTo[h]) ){
- sprintf(zErr, "segment %d missing from hashTo[%d]", pSeg->id, h);
- Tcl_SetResult(interp, zErr, TCL_VOLATILE);
- return TCL_ERROR;
- }
- }
- return TCL_OK;
- }
- /*
- ** The maximum number of segments in a boundary
- */
- #define MX_BOUND 1000
- /* Wallset_Delete */
- static void Wallset_Delete(ClientData clientData){
- Wallset *p = (Wallset *)clientData;
- Link *pLink = p->pAll;
- clearComptBoxCache(p);
- while( pLink ){
- Segment *pSeg = pLink->pLinkNode;
- pLink = pSeg->pAll.pNext;
- Tcl_Free((char *) pSeg );
- }
- Tcl_Free((char *) p );
- }
- /* Wallset_Clone */
- static int Wallset_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- ){
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("WALLSETs are not clonable", -1));
- /* For now... */
- return TCL_ERROR;
- }
- /* *PolygonHullVertex_ById */
- static PolygonHullVertex *PolygonHullVertex_ById(PolygonHull *pHull, int id){
- PolygonHullVertex *pVertex;
- pVertex = (PolygonHullVertex*)readiHashFind(&pHull->VertexHash, 0, id);
- return pVertex;
- }
- /* *PolygonHullVertex_ByCoords */
- static PolygonHullVertex *PolygonHullVertex_ByCoords(PolygonHull *pHull, VectorXYZ A){
- int h;
- Link *pLink;
- HashElem *i;
- PolygonHullVertex *pVertex;
- h = hashCoord3d(A[X_IDX],A[Y_IDX],A[X_IDX]);
- for(pLink = pHull->VertexHashCoords[h]; pLink; pLink=pLink->pNext){
- pVertex=pLink->pLinkNode;
- if(VectorXYZ_SamePoint(pVertex->center,A)) {
- return pVertex;
- }
- }
- /* The hash checks sometimes miss. Search all */
- for(i=readiHashFirst(&pHull->VertexHash); i; i=readiHashNext(i)) {
- PolygonHullVertex *pVertex=(PolygonHullVertex *)readiHashData(i);
- if(VectorXYZ_SamePoint(pVertex->center,A)) {
- return pVertex;
- }
- }
- return NULL;
- }
- /* *PolygonHullVertex_Create */
- static PolygonHullVertex *PolygonHullVertex_Create(
- PolygonHull *pHull,
- int id,
- VectorXYZ point
- ){
- int hx;
- PolygonHullVertex *pVertex;
- pVertex = (PolygonHullVertex *)Odie_Alloc( sizeof(PolygonHullVertex) );
- if( pVertex==NULL ) return NULL;
- if(id<0) {
- pHull->VertexNextId++;
- id=pHull->VertexNextId;
- } else if (id>=pHull->VertexNextId) {
- pHull->VertexNextId=id;
- }
- pVertex->id=id;
- LinkInit(pVertex->pHashVertexCoords, pVertex);
- readiHashInsert(&pHull->VertexHash, 0, id, pVertex);
- pVertex->center[X_IDX]=point[X_IDX];
- pVertex->center[Y_IDX]=point[Y_IDX];
- pVertex->center[Z_IDX]=point[Z_IDX];
- hx=hashCoord3d(point[X_IDX],point[Y_IDX],point[Z_IDX]);
- LinkInsert(&pHull->VertexHashCoords[hx], &pVertex->pHashVertexCoords);
- return pVertex;
- }
- /* PolygonHullVertex_Remove */
- static void PolygonHullVertex_Remove(PolygonHullVertex *pVertex){
- Link *pLink;
- for(pLink=pVertex->pHashFace;pLink;pLink=pLink->pNext) {
- PolygonHullFace *pFace=pLink->pLinkNode;
- if(pFace) {
- PolygonHullFace_Remove(pFace);
- }
- }
- LinkRemove(&pVertex->pHashVertexCoords);
- }
- /* *PolygonHullFace_VertexInject */
- static const char *PolygonHullFace_VertexInject(PolygonHullFace *pFace,PolygonHullVertex *pThisVertex){
- PolygonHullVertex *pVertex,*pPrior=NULL,*pFirst;
- PolygonHullFace_SerializeEdges(pFace);
- pFirst=pFace->pNextVertex;
- for(pVertex=pFirst;pVertex;pVertex=pVertex->pNextVertex) {
- if(VectorXYZ_SamePoint(pVertex->center,pThisVertex->center)) {
- /* Vertex already exists in polygon noop */
- return NULL;
- }
- pPrior=pVertex;
- }
- for(pVertex=pFirst;pVertex;pVertex=pVertex->pNextVertex) {
- if(VectorXYZ_PointIsOnSegment(pThisVertex->center,pPrior->center,pVertex->center)) {
- pThisVertex->pNextVertex=pVertex;
- if(pVertex==pFirst) {
- /* Head Insert */
- pFace->pNextVertex=pThisVertex;
- return NULL;
- } else {
- /* Mid segment insert */
- pPrior->pNextVertex=pThisVertex;
- return NULL;
- }
- }
- pPrior=pVertex;
- }
- /* Oh brother... */
- return "Could not break edge";
- }
- /* *PolygonHullFace_To_Dict */
- Tcl_Obj *PolygonHullFace_To_Dict(PolygonHullFace *pFace){
- Tcl_Obj *element=Tcl_NewObj();
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->id);
- Odie_DictObjPut(NULL,element,"id:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->nVertex);
- Odie_DictObjPut(NULL,element,"nVertex:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->wallid);
- Odie_DictObjPut(NULL,element,"wallid:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->deckid);
- Odie_DictObjPut(NULL,element,"deckid:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->typeid);
- Odie_DictObjPut(NULL,element,"typeid:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pFace->is_wall);
- Odie_DictObjPut(NULL,element,"is_wall:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pFace->is_exterior);
- Odie_DictObjPut(NULL,element,"is_exterior:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->is_virtual);
- Odie_DictObjPut(NULL,element,"is_virtual:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->idLC);
- Odie_DictObjPut(NULL,element,"idLC:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pFace->idRC);
- Odie_DictObjPut(NULL,element,"idRC:",value);
- }
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pFace->center);
- Odie_DictObjPut(NULL,element,"center:",value);
- }
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pFace->normal);
- Odie_DictObjPut(NULL,element,"normal:",value);
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewDoubleObj(pFace->radius);
- Odie_DictObjPut(NULL,element,"radius:",value);
- }
- {
- Tcl_Obj *value;
- char outbuf[64];
- int i;
- value=Tcl_NewObj();
- for(i=0;i<6;i++) {
- sprintf(outbuf,"%.3f",(float)pFace->bbox[i]);
- Tcl_ListObjAppendElement(NULL,value,Tcl_NewStringObj(outbuf,-1));
- }
- Odie_DictObjPut(NULL,element,"bbox:",value);
- }
- return element;}
- /* *PolygonHullFace_Create */
- static PolygonHullFace *PolygonHullFace_Create(
- PolygonHull *pHull,
- int id
- ){
- PolygonHullFace *pFace;
- pFace = (PolygonHullFace *)Odie_Alloc( sizeof(PolygonHullFace) );
- if( pFace==NULL ) return NULL;
- if(id<0) {
- pHull->FaceNextId++;
- id=pHull->FaceNextId;
- } else if (id>=pHull->FaceNextId) {
- pHull->FaceNextId=id;
- }
- pFace->id=id;
- readiHashInsert(&pHull->FaceHash, 0, id, pFace);
- pFace->id = id;
- pFace->pActive = pHull->pActive;
- pHull->pActive = pFace;
- LinkInit(pFace->pSet, pFace);
- return pFace;
- }
- /* *PolygonHull_mergeFaceList */
- static PolygonHullFace *PolygonHull_mergeFaceList(PolygonHullFace *a, PolygonHullFace *b){
- PolygonHullFace head, *pTail;
- pTail = &head;
- while( a && b ){
- if( a->dist <= b->dist ){
- pTail->pNext = a;
- pTail = a;
- a = a->pNext;
- }else{
- pTail->pNext = b;
- pTail = b;
- b = b->pNext;
- }
- }
- if( a ){
- pTail->pNext = a;
- }else if( b ){
- pTail->pNext = b;
- }else{
- pTail->pNext = 0;
- }
- return head.pNext;
- }
- /* *PolygonHull_sortFaceList */
- static PolygonHullFace *PolygonHull_sortFaceList(PolygonHullFace *pList){
- int i;
- PolygonHullFace *p;
- PolygonHullFace *ap[NBUCKET];
- for(i=0; i<NBUCKET; i++){ ap[i] = 0; }
- while( pList ){
- p = pList;
- pList = p->pNext;
- p->pNext = 0;
- for(i=0; i<NBUCKET-1; i++){
- if( ap[i] ){
- p = PolygonHull_mergeFaceList(ap[i], p);
- ap[i] = 0;
- }else{
- ap[i] = p;
- break;
- }
- }
- if( i==NBUCKET ){
- ap[i] = PolygonHull_mergeFaceList(ap[i],p);
- }
- }
- p = 0;
- for(i=0; i<NBUCKET; i++){
- p = PolygonHull_mergeFaceList(ap[i], p);
- }
- return p;
- }
- /* *PolygonHullFace_ById */
- static PolygonHullFace *PolygonHullFace_ById(PolygonHull *pHull, int id){
- PolygonHullFace *pFace;
- pFace = (PolygonHullFace*)readiHashFind(&pHull->FaceHash, 0, id);
- return pFace;
- }
- /* PolygonHull_findFace */
- static int PolygonHull_findFace(
- Tcl_Interp *interp, /* Leave any error message here */
- PolygonHull *pHull,
- Tcl_Obj *pObj, /* The PolygonHullFace ID */
- PolygonHullFace **ppHullFace /* Write PolygonHullFace pointer here */
- ){
- int id;
- if( Tcl_GetIntFromObj(interp, pObj, &id) ) return TCL_ERROR;
- *ppHullFace = PolygonHullFace_ById(pHull,id);
- if( *ppHullFace==0 ){
- Tcl_AppendResult(interp, "no such PolygonHullFace", 0);
- return TCL_ERROR;
- }
- PolygonHullFace_Compute(*ppHullFace);
- return TCL_OK;
- }
- /* PolygonHullFace_Remove */
- static void PolygonHullFace_Remove(PolygonHullFace *pFace){
- int i;
- if(!pFace) return;
- LinkRemove(&pFace->pSet);
- if(pFace->aVertex) {
- for(i=0;i<pFace->nVertex;i++) {
- if(pFace->aVertex[i]==0) continue;
- LinkRemove(&pFace->pVertex[i]);
- }
- Odie_Free((char *)pFace->aVertex);
- }
- if(pFace->pVertex) {
- Odie_Free((char *)pFace->pVertex);
- }
- }
- /* PolygonHullFace_SerializeEdges */
- static void PolygonHullFace_SerializeEdges(PolygonHullFace *p){
- int i;
- PolygonHullVertex *pPrior=NULL,*pVertex;
- if(p->pNextVertex) {
- return;
- }
- //printf("PolygonHullFace_SerializeEdges %d %p\n",p->id,p->aVertex);
- for(i=0;i<p->nVertex;i++) {
- pVertex=p->aVertex[i];
- assert(pVertex);
- LinkRemove(&p->pVertex[i]);
- //printf("PolygonHullFace_SerializeEdges %d #%d %p %p\n",p->id,i,pPrior,pVertex);
- pVertex->pNextVertex=NULL;
- if(!pPrior) {
- p->pNextVertex=pVertex;
- } else {
- pPrior->pNextVertex=pVertex;
- }
- pPrior=pVertex;
- }
- //printf("PolygonHullFace_SerializeEdges %d LAST %d %p\n",p->id,i,pPrior);
- if(pPrior) {
- pPrior->pNextVertex=NULL;
- }
- Odie_Free(p->aVertex);
- Odie_Free(p->pVertex);
- p->nVertex=0;
- p->aVertex=NULL;
- p->pVertex=NULL;
- }
- /* PolygonHullFace_Compute */
- static void PolygonHullFace_Compute(PolygonHullFace *pFace){
- VectorXYZ one,two;
- int i;
- double r1,rmax;
- int nVertex;
- PolygonHullVertex *pVertex,*pFirst;
- //printf("PolygonHullFace_Compute %d %p %p\n",pFace->id,pFace,pFace->pNextVertex);
- if(!pFace->pNextVertex) {
- return;
- }
- VectorXYZ_AABB_Reset(pFace->bbox);
- nVertex=0;
- /* Count the number of vertices */
- pFirst=pFace->pNextVertex;
- for(pVertex=pFirst;pVertex;pVertex=pVertex->pNextVertex) {
- nVertex++;
- if(nVertex>32) break;
- }
- pFace->nVertex=nVertex;
- /* Allocate the arrays to store the vertices */
- pFace->aVertex=(PolygonHullVertex **)Odie_Alloc(sizeof(PolygonHullVertex *)*pFace->nVertex);
- pFace->pVertex=(Link *)Odie_Alloc(sizeof(Link)*pFace->nVertex);
- pVertex=pFirst;
- for(i=0;i<nVertex;i++) {
- VectorXYZ_AABB_Measure(pVertex->center,pFace->bbox);
- pFace->pNextVertex=pVertex->pNextVertex;
- pFace->aVertex[i]=pVertex;
- LinkInit(pFace->pVertex[i],pFace);
- LinkInsert(&pVertex->pHashFace, &pFace->pVertex[i]);
- pVertex=pVertex->pNextVertex;
- }
- for(i=0;i<nVertex;i++) {
- pVertex=pFace->aVertex[i];
- pVertex->pNextVertex=NULL;
- }
- if(pFace->nVertex==3) {
- VectorXYZ_Subtract(one, pFace->aVertex[1]->center, pFace->aVertex[0]->center);
- VectorXYZ_Subtract(two, pFace->aVertex[2]->center, pFace->aVertex[0]->center);
- pFace->normal[X_IDX] = one[Y_IDX]*two[Z_IDX] - one[Z_IDX]*two[Y_IDX];
- pFace->normal[Y_IDX] = one[Z_IDX]*two[X_IDX] - one[X_IDX]*two[Z_IDX];
- pFace->normal[Z_IDX] = one[X_IDX]*two[Y_IDX] - one[Y_IDX]*two[X_IDX];
- } else {
- int i,j;
- VectorXYZ_Zero(pFace->normal);
- for(i=0,j=1;i<pFace->nVertex;i++,j++) {
- if(j==pFace->nVertex) j=0;
- pFace->normal[X_IDX] += (pFace->aVertex[j]->center[Y_IDX]-pFace->aVertex[i]->center[Y_IDX]) * (pFace->aVertex[j]->center[Z_IDX]+pFace->aVertex[i]->center[Z_IDX]);
- pFace->normal[Y_IDX] += (pFace->aVertex[j]->center[Z_IDX]-pFace->aVertex[i]->center[Z_IDX]) * (pFace->aVertex[j]->center[X_IDX]+pFace->aVertex[i]->center[X_IDX]);
- pFace->normal[Z_IDX] += (pFace->aVertex[j]->center[X_IDX]-pFace->aVertex[i]->center[X_IDX]) * (pFace->aVertex[j]->center[Y_IDX]+pFace->aVertex[i]->center[Y_IDX]);
- }
- }
- VectorXYZ_Normalize(pFace->normal);
- /* Compute the center and radius of the face. */
- VectorXYZ_Zero(pFace->center);
- for(i=0; i<pFace->nVertex; i++){
- pFace->center[X_IDX] += pFace->aVertex[i]->center[X_IDX];
- pFace->center[Y_IDX] += pFace->aVertex[i]->center[Y_IDX];
- pFace->center[Z_IDX] += pFace->aVertex[i]->center[Z_IDX];
- }
- pFace->center[X_IDX] /= pFace->nVertex;
- pFace->center[Y_IDX] /= pFace->nVertex;
- pFace->center[Z_IDX] /= pFace->nVertex;
- rmax=0.0;
- for(i=0; i<pFace->nVertex; i++){
- r1 = VectorXYZ_DistanceSq(pFace->center, pFace->aVertex[i]->center);
- if(r1>rmax) {
- rmax=r1;
- }
- }
- pFace->radiusSq = rmax;
- pFace->radius = sqrt(rmax);
- }
- /* PolygonHull_sqrDistPointToEdge */
- static double PolygonHull_sqrDistPointToEdge(
- VectorXYZ A, VectorXYZ B, /* End points of the line segment */
- VectorXYZ X /* The point to measure distance to */
- ){
- VectorXYZ closest; /* Point on line segment closest to X */
- VectorXYZ_ClosestPointOnSegment(A,B,X,closest);
- return VectorXYZ_DistanceSq(X, closest);
- }
- /* PolygonHull_intersectLineSegFace */
- static double PolygonHull_intersectLineSegFace(
- PolygonHullFace *pFace, /* The triangle we are trying to intersect */
- VectorXYZ pStart, /* Start of the line segment */
- VectorXYZ pEnd, /* End of the line segment */
- VectorXYZ pIntersect /* Point of intersection written here if not NULL */
- ){
- double d;
- int i;
- for(i=2;i<pFace->nVertex;i++) {
- /*
- ** Assuming we are fed convex polygons,
- ** break the surface into triangles
- ** and evaluate each triangle
- */
- d = VectorXYZ_TriangleLineIntersect(pFace->aVertex[0]->center,pFace->aVertex[i-1]->center,pFace->aVertex[i]->center,pStart,pEnd,pIntersect);
- if(d>=0.0) {
- return d;
- }
- }
- return -1.0;
- }
- /* *PolygonHullFace_findHits */
- static PolygonHullFace *PolygonHullFace_findHits(PolygonHull *pHull, VectorXYZ A, VectorXYZ B){
- PolygonHullFace *p, *pList;
- double d1, d2;
- pList = 0;
- for(p=pHull->pActive; p; p=p->pActive){
- d1 = PolygonHull_sqrDistPointToEdge(A, B, p->center);
- d2 = p->radiusSq;
- if( d2<d1 ){
- continue;
- }
- d1 = PolygonHull_intersectLineSegFace(p, A, B,p->intersect);
- if( d1>=0.0 ){
- p->pNext = pList;
- pList = p;
- p->dist = d1;
- }
- }
- return PolygonHull_sortFaceList(pList);
- }
- /* PolygonHull_closestPointOnFace */
- static double PolygonHull_closestPointOnFace(PolygonHullFace *p, VectorXYZ X, VectorXYZ R){
- double d1, d2, distBest=1e99;
- VectorXYZ testPt;
- VectorXYZ a, b; /* End points of line seg parallel to p->normal */
- int i,j;
- /* Construct a line segment a->b that is parallel to p->normal and which
- ** passes through X. Make sure the line segment is plenty long
- ** enough so that it will intersect the plane of p.
- */
- d1 = VectorXYZ_Distance(X, p->center)*2;
- d2 = p->normal[X_IDX]*d1;
- a[X_IDX] = X[X_IDX] + d2;
- b[X_IDX] = X[X_IDX] - d2;
- d2 = p->normal[Y_IDX]*d1;
- a[Y_IDX] = X[Y_IDX] + d2;
- b[Y_IDX] = X[Y_IDX] - d2;
- d2 = p->normal[Z_IDX]*d1;
- a[Z_IDX] = X[Z_IDX] + d2;
- b[Z_IDX] = X[Z_IDX] - d2;
- /* Figure out if a->b intersects the triangle, and if so where. If
- ** there is an intersection, then this is the closest point.
- */
- if( PolygonHull_intersectLineSegFace(p, a, b, R)>=0.0 ){
- return VectorXYZ_Distance(X,R);
- }
- /*
- ** If we reach here it means that the closest point will be on the
- ** permiter of the triangle. There are three line faces on the
- ** permiter. Try them all.
- */
- for(i=0,j=1;i<p->nVertex;i++,j++) {
- if(j==p->nVertex) j=0;
- VectorXYZ_ClosestPointOnSegment(p->aVertex[i]->center, p->aVertex[j]->center, X, testPt);
- d1 = VectorXYZ_Distance(X, testPt);
- if(i==0 || d1<distBest) {
- distBest = d1;
- R[X_IDX]=testPt[X_IDX];
- R[Y_IDX]=testPt[Y_IDX];
- R[Z_IDX]=testPt[Z_IDX];
- }
- }
- return distBest;
- }
- /* *PolygonHullFace_findClosest */
- static PolygonHullFace *PolygonHullFace_findClosest(PolygonHull *pHull,VectorXYZ X, VectorXYZ R, double *pDist){
- double d1;
- double distBest=1e99;
- PolygonHullFace *pBest=NULL;
- VectorXYZ testPt;
- PolygonHullFace *p;
- HashElem *i;
- /* First pass: Locate the triangle whose center is closest to X.
- ** This will be our first guess of what the closest triangle is.
- ** And because it is probably pretty close to the best, it will make
- ** it easy to eliminate other triangles from contention.
- */
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- p = readiHashData(i);
- d1 = VectorXYZ_DistanceSq(p->center, X);
- if( pBest==0 || d1<distBest ){
- pBest = p;
- distBest = d1;
- }
- }
- if( pBest==0 ){
- return 0;
- }
- /* Compute the exact distance from X to our first guess at the closest
- ** triangle.
- */
- d1=PolygonHull_closestPointOnFace(pBest, X, R);
- distBest = d1*d1;
- /* Do a second pass over the data to see if we can find another
- ** triangle that is closer than pBest. We only need to check
- ** triangle whose center is not further away from X than distBest
- ** plus the triangle radius.
- */
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- p = readiHashData(i);
- if( p==pBest ){
- continue;
- }
- d1 = VectorXYZ_DistanceSq(p->center, X);
- if( d1 - p->radiusSq > distBest ){
- continue;
- }
- d1 = PolygonHull_closestPointOnFace(p, X, testPt);
- if( (d1*d1)<distBest ){
- pBest = p;
- distBest = d1*d1;
- R[X_IDX] = testPt[X_IDX];
- R[Y_IDX] = testPt[Y_IDX];
- R[Z_IDX] = testPt[Z_IDX];
- }
- }
- *pDist = sqrt(distBest);
- return pBest;
- }
- /* *PolygonHullVolume_ById */
- static PolygonHullVolume *PolygonHullVolume_ById(PolygonHull *pHull, int id){
- PolygonHullVolume *pVolume;
- pVolume = readiHashFind(&pHull->VolumeHash, 0, id);
- return pVolume;
- }
- /* *PolygonHullVolume_Create */
- static PolygonHullVolume *PolygonHullVolume_Create(
- PolygonHull *pHull,
- int id
- ){
- PolygonHullVolume *pVolume;
- pVolume = (PolygonHullVolume *)Odie_Alloc( sizeof(PolygonHullVolume) );
- if( pVolume==NULL ) return NULL;
- if(id<0) {
- pHull->VolumeNextId++;
- id=pHull->VolumeNextId;
- } else if (id>=pHull->VolumeNextId) {
- pHull->VolumeNextId=id;
- }
- pVolume->id=id;
- readiHashInsert(&pHull->VolumeHash, 0, id, pVolume);
- return pVolume;
- }
- /* PolygonHullVolume_Unlink */
- static void PolygonHullVolume_Unlink(PolygonHullVolume *pVolume){
- }
- /* PolygonHull_clearSurfaces */
- static void PolygonHull_clearSurfaces(PolygonHull *pHull){
- }
- /* PolygonHull_Reset */
- static void PolygonHull_Reset(PolygonHull *pHull){
- PolygonHull_clearSurfaces(pHull);
- pHull->FaceNextId=0;
- pHull->VertexNextId=0;
- pHull->VolumeNextId=0;
- HashElem *i;
- for(i=readiHashFirst(&pHull->VolumeHash); i; i=readiHashNext(i)) {
- char *ptr=(char *)readiHashData(i);
- Odie_Free((char *)ptr);
- }
- readiHashClear(&pHull->VolumeHash);
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- char *ptr=(char *)readiHashData(i);
- Odie_Free((char *)ptr);
- }
- readiHashClear(&pHull->FaceHash);
- for(i=readiHashFirst(&pHull->VertexHash); i; i=readiHashNext(i)) {
- char *ptr=(char *)readiHashData(i);
- Odie_Free((char *)ptr);
- }
- readiHashClear(&pHull->VertexHash);
- }
- /* PolygonHull_Delete */
- static void PolygonHull_Delete(ClientData clientData){
- PolygonHull *pHull = (PolygonHull *)clientData;
- PolygonHull_Reset(pHull);
- Odie_Free((char *) pHull);
- }
- /* PolygonHull_Clone */
- static int PolygonHull_Clone(
- Tcl_Interp* interp, /* Tcl interpreter for error reporting */
- ClientData metadata, /* Metadata to be cloned */
- ClientData* newMetaData /* Where to put the cloned metadata */
- ){
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj("POLYGONHULLs are not clonable", -1));
- /* For now... */
- return TCL_ERROR;
- }
- /* *Odie_Obj_To_Int */
- Tcl_Obj *Odie_Obj_To_Int(Tcl_Obj *tclObj){
- int sint;
- double s;
- if (Tcl_GetIntFromObj(NULL,tclObj,&sint)==TCL_OK) {
- return tclObj;
- }
- if (Tcl_GetDoubleFromObj(NULL,tclObj,&s)) {
- return tclObj;
- }
- return Tcl_NewIntObj((int)round(s));
- }
- /* Odie_trace_printf */
- void Odie_trace_printf(Tcl_Interp *interp,const char *zFormat, ...){
- /*
- ** Print a trace message
- */
- int n;
- va_list ap;
- char zBuf[4000];
- va_start(ap, zFormat);
- strcpy(zBuf, "puts -nonewline \x7b");
- n = strlen(zBuf);
- vsnprintf(&zBuf[n], sizeof(zBuf)-5-n, zFormat, ap);
- strcat(zBuf, "\x7d\n");
- Tcl_Eval(interp, zBuf);
- }
- /*
- *----------------------------------------------------------------------
- *
- * MergeLists -
- *
- * This procedure combines two sorted lists of SortElement structures
- * into a single sorted list.
- *
- * Results:
- * The unified list of SortElement structures.
- *
- * Side effects:
- * If infoPtr->unique is set then infoPtr->numElements may be updated.
- * Possibly others, if a user-defined comparison command does something
- * weird.
- *
- * Note:
- * If infoPtr->unique is set, the merge assumes that there are no
- * "repeated" elements in each of the left and right lists. In that case,
- * if any element of the left list is equivalent to one in the right list
- * it is omitted from the merged list.
- * This simplified mechanism works because of the special way
- * our MergeSort creates the sublists to be merged and will fail to
- * eliminate all repeats in the general case where they are already
- * present in either the left or right list. A general code would need to
- * skip adjacent initial repeats in the left and right lists before
- * comparing their initial elements, at each step.
- *----------------------------------------------------------------------
- */
- static SortElement *
- MergeLists(
- SortElement *leftPtr, /* First list to be merged; may be NULL. */
- SortElement *rightPtr, /* Second list to be merged; may be NULL. */
- SortInfo *infoPtr) /* Information needed by the comparison
- * operator. */
- {
- SortElement *headPtr, *tailPtr;
- int cmp;
- if (leftPtr == NULL) {
- return rightPtr;
- }
- if (rightPtr == NULL) {
- return leftPtr;
- }
- cmp = SortCompare(leftPtr, rightPtr, infoPtr);
- if (cmp > 0 || (cmp == 0 && infoPtr->unique)) {
- if (cmp == 0) {
- infoPtr->numElements--;
- leftPtr = leftPtr->nextPtr;
- }
- tailPtr = rightPtr;
- rightPtr = rightPtr->nextPtr;
- } else {
- tailPtr = leftPtr;
- leftPtr = leftPtr->nextPtr;
- }
- headPtr = tailPtr;
- if (!infoPtr->unique) {
- while ((leftPtr != NULL) && (rightPtr != NULL)) {
- cmp = SortCompare(leftPtr, rightPtr, infoPtr);
- if (cmp > 0) {
- tailPtr->nextPtr = rightPtr;
- tailPtr = rightPtr;
- rightPtr = rightPtr->nextPtr;
- } else {
- tailPtr->nextPtr = leftPtr;
- tailPtr = leftPtr;
- leftPtr = leftPtr->nextPtr;
- }
- }
- } else {
- while ((leftPtr != NULL) && (rightPtr != NULL)) {
- cmp = SortCompare(leftPtr, rightPtr, infoPtr);
- if (cmp >= 0) {
- if (cmp == 0) {
- infoPtr->numElements--;
- leftPtr = leftPtr->nextPtr;
- }
- tailPtr->nextPtr = rightPtr;
- tailPtr = rightPtr;
- rightPtr = rightPtr->nextPtr;
- } else {
- tailPtr->nextPtr = leftPtr;
- tailPtr = leftPtr;
- leftPtr = leftPtr->nextPtr;
- }
- }
- }
- if (leftPtr != NULL) {
- tailPtr->nextPtr = leftPtr;
- } else {
- tailPtr->nextPtr = rightPtr;
- }
- return headPtr;
- }
- /*
- *----------------------------------------------------------------------
- *
- * SortCompare --
- *
- * This procedure is invoked by MergeLists to determine the proper
- * ordering between two elements.
- *
- * Results:
- * A negative results means the the first element comes before the
- * second, and a positive results means that the second element should
- * come first. A result of zero means the two elements are equal and it
- * doesn't matter which comes first.
- *
- * Side effects:
- * None, unless a user-defined comparison command does something weird.
- *
- *----------------------------------------------------------------------
- */
- static int
- SortCompare(
- SortElement *elemPtr1, SortElement *elemPtr2,
- /* Values to be compared. */
- SortInfo *infoPtr) /* Information passed from the top-level
- * "lsort" command. */
- {
- int order = 0;
- if (infoPtr->sortMode == SORTMODE_ASCII) {
- order = strcmp(elemPtr1->index.strValuePtr,
- elemPtr2->index.strValuePtr);
- } else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
- order = strcasecmp(elemPtr1->index.strValuePtr,
- elemPtr2->index.strValuePtr);
- } else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
- order = DictionaryCompare(elemPtr1->index.strValuePtr,
- elemPtr2->index.strValuePtr);
- } else if (infoPtr->sortMode == SORTMODE_INTEGER) {
- long a, b;
- a = elemPtr1->index.intValue;
- b = elemPtr2->index.intValue;
- order = ((a >= b) - (a <= b));
- } else if (infoPtr->sortMode == SORTMODE_REAL) {
- double a, b;
- a = elemPtr1->index.doubleValue;
- b = elemPtr2->index.doubleValue;
- order = ((a >= b) - (a <= b));
- } else {
- Tcl_Obj **objv, *paramObjv[2];
- int objc;
- Tcl_Obj *objPtr1, *objPtr2;
- if (infoPtr->resultCode != TCL_OK) {
- /*
- * Once an error has occurred, skip any future comparisons so as
- * to preserve the error message in sortInterp->result.
- */
- return 0;
- }
- objPtr1 = elemPtr1->index.objValuePtr;
- objPtr2 = elemPtr2->index.objValuePtr;
- paramObjv[0] = objPtr1;
- paramObjv[1] = objPtr2;
- /*
- * We made space in the command list for the two things to compare.
- * Replace them and evaluate the result.
- */
- Tcl_ListObjLength(infoPtr->interp, infoPtr->compareCmdPtr, &objc);
- Tcl_ListObjReplace(infoPtr->interp, infoPtr->compareCmdPtr, objc - 2,
- 2, 2, paramObjv);
- Tcl_ListObjGetElements(infoPtr->interp, infoPtr->compareCmdPtr,
- &objc, &objv);
- infoPtr->resultCode = Tcl_EvalObjv(infoPtr->interp, objc, objv, 0);
- if (infoPtr->resultCode != TCL_OK) {
- Tcl_AddErrorInfo(infoPtr->interp,
- "\n (-compare command)");
- return 0;
- }
- /*
- * Parse the result of the command.
- */
- if (Tcl_GetIntFromObj(infoPtr->interp,
- Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) {
- Tcl_ResetResult(infoPtr->interp);
- Tcl_AppendResult(infoPtr->interp,
- "-compare command returned non-integer result", NULL);
- infoPtr->resultCode = TCL_ERROR;
- return 0;
- }
- }
- if (!infoPtr->isIncreasing) {
- order = -order;
- }
- return order;
- }
- /*
- *----------------------------------------------------------------------
- *
- * DictionaryCompare
- *
- * This function compares two strings as if they were being used in an
- * index or card catalog. The case of alphabetic characters is ignored,
- * except to break ties. Thus "B" comes before "b" but after "a". Also,
- * integers embedded in the strings compare in numerical order. In other
- * words, "x10y" comes after "x9y", not * before it as it would when
- * using strcmp().
- *
- * Results:
- * A negative result means that the first element comes before the
- * second, and a positive result means that the second element should
- * come first. A result of zero means the two elements are equal and it
- * doesn't matter which comes first.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- static int
- DictionaryCompare(
- char *left, char *right) /* The strings to compare. */
- {
- Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
- int diff, zeros;
- int secondaryDiff = 0;
- while (1) {
- if (isdigit(UCHAR(*right)) /* INTL: digit */
- && isdigit(UCHAR(*left))) { /* INTL: digit */
- /*
- * There are decimal numbers embedded in the two strings. Compare
- * them as numbers, rather than strings. If one number has more
- * leading zeros than the other, the number with more leading
- * zeros sorts later, but only as a secondary choice.
- */
- zeros = 0;
- while ((*right == '0') && (isdigit(UCHAR(right[1])))) {
- right++;
- zeros--;
- }
- while ((*left == '0') && (isdigit(UCHAR(left[1])))) {
- left++;
- zeros++;
- }
- if (secondaryDiff == 0) {
- secondaryDiff = zeros;
- }
- /*
- * The code below compares the numbers in the two strings without
- * ever converting them to integers. It does this by first
- * comparing the lengths of the numbers and then comparing the
- * digit values.
- */
- diff = 0;
- while (1) {
- if (diff == 0) {
- diff = UCHAR(*left) - UCHAR(*right);
- }
- right++;
- left++;
- if (!isdigit(UCHAR(*right))) { /* INTL: digit */
- if (isdigit(UCHAR(*left))) { /* INTL: digit */
- return 1;
- } else {
- /*
- * The two numbers have the same length. See if their
- * values are different.
- */
- if (diff != 0) {
- return diff;
- }
- break;
- }
- } else if (!isdigit(UCHAR(*left))) { /* INTL: digit */
- return -1;
- }
- }
- continue;
- }
- /*
- * Convert character to Unicode for comparison purposes. If either
- * string is at the terminating null, do a byte-wise comparison and
- * bail out immediately.
- */
- if ((*left != '\0') && (*right != '\0')) {
- left += Tcl_UtfToUniChar(left, &uniLeft);
- right += Tcl_UtfToUniChar(right, &uniRight);
- /*
- * Convert both chars to lower for the comparison, because
- * dictionary sorts are case insensitve. Covert to lower, not
- * upper, so chars between Z and a will sort before A (where most
- * other interesting punctuations occur).
- */
- uniLeftLower = Tcl_UniCharToLower(uniLeft);
- uniRightLower = Tcl_UniCharToLower(uniRight);
- } else {
- diff = UCHAR(*left) - UCHAR(*right);
- break;
- }
- diff = uniLeftLower - uniRightLower;
- if (diff) {
- return diff;
- }
- if (secondaryDiff == 0) {
- if (Tcl_UniCharIsUpper(uniLeft) && Tcl_UniCharIsLower(uniRight)) {
- secondaryDiff = -1;
- } else if (Tcl_UniCharIsUpper(uniRight)
- && Tcl_UniCharIsLower(uniLeft)) {
- secondaryDiff = 1;
- }
- }
- }
- if (diff == 0) {
- diff = secondaryDiff;
- }
- return diff;
- }
- static int Odie_SortElement_FromObj(
- Tcl_Interp *interp,
- int sortMode,
- Tcl_Obj *valuePtr,
- SortElement *elementPtr
- ) {
- /*
- * Determine the "value" of this object for sorting purposes
- */
- if (sortMode == SORTMODE_ASCII) {
- elementPtr->index.strValuePtr = Tcl_GetString(valuePtr);
- } else if (sortMode == SORTMODE_INTEGER) {
- long a;
- if (Tcl_GetLongFromObj(interp, valuePtr, &a) != TCL_OK) {
- return TCL_ERROR;
- }
- elementPtr->index.intValue = a;
- } else if (sortMode == SORTMODE_REAL) {
- double a;
- if (Tcl_GetDoubleFromObj(interp, valuePtr, &a) != TCL_OK) {
- return TCL_ERROR;
- }
- elementPtr->index.doubleValue = a;
- } else {
- elementPtr->index.objValuePtr = valuePtr;
- }
- elementPtr->objPtr = valuePtr;
- return TCL_OK;
- }
- /* *Odie_MergeList_ToObj */
- static Tcl_Obj *Odie_MergeList_ToObj(SortElement *elementPtr){
- /*
- ** Converts a linked list of structures into
- ** a Tcl list object
- */
- SortElement *loopPtr;
- Tcl_Obj **newArray;
- int i,len=0;
- loopPtr=elementPtr;
- for (len=0; loopPtr != NULL ; loopPtr = loopPtr->nextPtr) {
- len++;
- }
- newArray = (Tcl_Obj **)Odie_Alloc(sizeof(Tcl_Obj *)*len);
- loopPtr=elementPtr;
- for (i=0; loopPtr != NULL ; loopPtr = loopPtr->nextPtr) {
- Tcl_Obj *objPtr = loopPtr->objPtr;
- newArray[i] = objPtr;
- i++;
- //Tcl_IncrRefCount(objPtr);
- }
- return Tcl_NewListObj(len,newArray);
- }
- /* Odie_Lsearch */
- STUB_EXPORT int Odie_Lsearch(int listLength,Tcl_Obj **listObjPtrs,Tcl_Obj *element){
- int i;
- Tcl_Obj *o;
- if(element==NULL) {
- return -1;
- }
- int matchLen;
- char *match=Tcl_GetStringFromObj(element,&matchLen);
- int s2len,found;
- const char *s2;
- if(matchLen < 0) {
- return -1;
- }
- found = 0;
- for(i=0;i<listLength && !found;i++) {
- o=listObjPtrs[i];
- if (o != NULL) {
- s2 = Tcl_GetStringFromObj(o, &s2len);
- } else {
- s2 = "";
- }
- if (matchLen == s2len) {
- found = (strcmp(match, s2) == 0);
- if(found) {
- return i;
- }
- }
- }
- return -1;
- }
- /* *Logicset_To_TclObj */
- STUB_EXPORT Tcl_Obj *Logicset_To_TclObj(Tcl_Obj *set){
- if(set) {
- return Tcl_DuplicateObj(set);
- } else {
- return Tcl_NewObj();
- }
- }
- /* Logicset_LIST_RESET */
- STUB_EXPORT void Logicset_LIST_RESET(Tcl_Obj **set){
- if(*set) {
- Tcl_DecrRefCount(*set);
- }
- *set=Tcl_NewObj();
- }
- /* Logicset_LIST_CONTAINS */
- STUB_EXPORT int Logicset_LIST_CONTAINS(Tcl_Obj **aPtrs,int aLength,Tcl_Obj *element){
- if(element==NULL) return 0;
- if(aLength<1) return 0;
- int matchIdx=Odie_Lsearch(aLength,aPtrs,element);
- if(matchIdx>=0) {
- return 1;
- }
- return 0;
- }
- /* Logicset_Sanitize_List */
- STUB_EXPORT void Logicset_Sanitize_List(char *value,int len){
- int i,skipped=0;
- for(i=0;i<len;i++) {
- unsigned char x=value[i];
- skipped++;
- /* Anything outside this range in non-printable, whitespace, or a delimeter */
- if(x<0x30 || x>0x80 || x==0x7D || x==0x7B) {
- value[i]=0x20;
- continue;
- }
- skipped--;
- }
- }
- /* *Logicset_FromObj */
- STUB_EXPORT Tcl_Obj *Logicset_FromObj(Tcl_Obj *rawlist){
- if(!rawlist) {
- return NULL;
- }
- int len;
- char *rawvalue=Tcl_GetStringFromObj(rawlist,&len);
- if(len==0) {
- return NULL;
- }
- Logicset_Sanitize_List(rawvalue,len);
- Tcl_Obj *tempString=Tcl_NewStringObj(rawvalue,len);
- int listLength,i;
- Tcl_Obj **listObjPtrs;
- if(Tcl_ListObjGetElements(NULL, tempString, &listLength, &listObjPtrs)) {
- Tcl_DecrRefCount(tempString);
- return NULL;
- }
- if(listLength <= 0) {
- Tcl_DecrRefCount(tempString);
- return NULL;
- }
- Tcl_Obj *listObj=Tcl_NewObj();
- for(i=0;i<listLength;i++) {
- Logicset_Add(listObj,listObjPtrs[i]);
- }
- Tcl_DecrRefCount(tempString);
- return listObj;
- }
- /* Logicset_Add */
- STUB_EXPORT int Logicset_Add(Tcl_Obj *aset,Tcl_Obj *element){
- int listLength;
- int i;
- Tcl_Obj **listObjPtrs;
- if(element==NULL) {
- return TCL_OK;
- }
- int matchLen;
- char *match=Tcl_GetStringFromObj(element,&matchLen);
- int s2len;
- const char *s2;
- if(matchLen < 0) {
- return TCL_ERROR;
- }
- if(Tcl_ListObjGetElements(NULL, aset, &listLength, &listObjPtrs)) {
- return TCL_ERROR;
- }
- /* Check that item isn't in list already */
- int found = 0;
- for(i=0;i<listLength && !found;i++) {
- Tcl_Obj *o=listObjPtrs[i];
- if (o != NULL) {
- s2 = Tcl_GetStringFromObj(o, &s2len);
- } else {
- s2 = "";
- }
- if (matchLen == s2len) {
- found = (strcmp(match, s2) == 0);
- if(found) {
- return TCL_OK;
- }
- }
- }
- for(i=0;i<listLength;i++) {
- int cmp = 0;
- Tcl_Obj *o=listObjPtrs[i];
- if (o != NULL) {
- s2 = Tcl_GetStringFromObj(o, &s2len);
- } else {
- s2 = "";
- }
- cmp = strcmp(match, s2);
- if(cmp==0) {
- return TCL_OK;
- } else if (cmp<0) {
- Tcl_Obj *NewVals[1];
- NewVals[0]=element;
- /* Add the new element here */
- return Tcl_ListObjReplace(NULL,aset,i,0,1,NewVals);
- }
- }
- Tcl_ListObjAppendElement(NULL,aset,element);
- return TCL_OK;
- }
- /* Logicset_Include */
- STUB_EXPORT void Logicset_Include(Tcl_Obj *aset,Tcl_Obj *bset){
- /*
- ** Add all elements of A and B together into a new set
- */
- if(!aset || !bset) {
- return;
- }
- int bLength;
- Tcl_Obj **bPtrs;
- if(Tcl_ListObjGetElements(0, bset, &bLength, &bPtrs)) {
- return;
- }
- if(bLength==0) {
- return;
- }
- if(bLength>1) {
- int i;
- for(i=0;i<bLength;i++) {
- Logicset_Include(aset,bPtrs[i]);
- }
- } else {
- if(Logicset_Add(aset,bPtrs[0])) {
- return;
- }
- }
- return;
- }
- /* Logicset_EXPR_AND */
- STUB_EXPORT int Logicset_EXPR_AND(Tcl_Obj *aset,Tcl_Obj *bset){
- /*
- ** Returns 1 if all elements in B are contained in A
- */
- int aLength;
- Tcl_Obj **aPtrs;
- if(!aset || !bset) return 0;
- if(Tcl_ListObjGetElements(0, aset, &aLength, &aPtrs)) {
- return 0;
- }
- int bLength;
- Tcl_Obj **bPtrs;
- if(Tcl_ListObjGetElements(0, bset, &bLength, &bPtrs)) {
- return 0;
- }
- int i;
- for(i=0;i<bLength;i++) {
- int found=Logicset_LIST_CONTAINS(aPtrs,aLength,bPtrs[i]);
- if(!found) {
- return 0;
- }
- }
- return 1;
- }
- /* Logicset_EXPR_OR */
- STUB_EXPORT int Logicset_EXPR_OR(Tcl_Obj *aset,Tcl_Obj *bset){
- int aLength;
- Tcl_Obj **aPtrs;
- if(!aset || !bset) return 0;
- if(Tcl_ListObjGetElements(0, aset, &aLength, &aPtrs)) {
- return 0;
- }
- int bLength;
- Tcl_Obj **bPtrs;
- if(Tcl_ListObjGetElements(0, bset, &bLength, &bPtrs)) {
- return 0;
- }
- int i;
- for(i=0;i<bLength;i++) {
- int found=Logicset_LIST_CONTAINS(aPtrs,aLength,bPtrs[i]);
- if(found) {
- return 1;
- }
- }
- return 0;
- }
- /* *Logicset_PRODUCT_INTERSECT */
- STUB_EXPORT Tcl_Obj *Logicset_PRODUCT_INTERSECT(Tcl_Obj *aset,Tcl_Obj *bset){
- int aLength;
- Tcl_Obj **aPtrs;
- if(!aset) {
- return bset;
- }
- if(!bset) {
- return aset;
- }
- if(Tcl_ListObjGetElements(0, aset, &aLength, &aPtrs)) return bset;
- int bLength;
- Tcl_Obj **bPtrs;
- if(Tcl_ListObjGetElements(0, bset, &bLength, &bPtrs)) return aset;
- int i,resultlen=0;
- Tcl_Obj *result=Tcl_NewObj();
- for(i=0;i<bLength;i++) {
- int found=Logicset_LIST_CONTAINS(aPtrs,aLength,bPtrs[i]);
- if(found) {
- resultlen++;
- Logicset_Add(result,bPtrs[i]);
- }
- }
- if(!resultlen) {
- Tcl_DecrRefCount(result);
- return NULL;
- }
- return result;
- }
- /* *Logicset_PRODUCT_UNION */
- STUB_EXPORT Tcl_Obj *Logicset_PRODUCT_UNION(Tcl_Obj *aset,Tcl_Obj *bset){
- if(!aset) {
- return bset;
- }
- if(!bset) {
- return aset;
- }
- Tcl_Obj *listObj=Tcl_NewObj();
- Logicset_Include(listObj,aset);
- Logicset_Include(listObj,bset);
- return listObj;
- }
- /* *Logicset_PRODUCT_XOR */
- STUB_EXPORT Tcl_Obj *Logicset_PRODUCT_XOR(Tcl_Obj *aset,Tcl_Obj *bset){
- int aLength;
- Tcl_Obj **aPtrs;
- if(!aset) {
- return bset;
- }
- if(!bset) {
- return aset;
- }
- if(Tcl_ListObjGetElements(0, aset, &aLength, &aPtrs)) return bset;
- int bLength;
- Tcl_Obj **bPtrs;
- if(Tcl_ListObjGetElements(0, bset, &bLength, &bPtrs)) return aset;
- int i,resultlen=0;
- Tcl_Obj *result=Tcl_NewObj();
- for(i=0;i<bLength;i++) {
- int found=Logicset_LIST_CONTAINS(aPtrs,aLength,bPtrs[i]);
- if(!found) {
- resultlen++;
- Logicset_Add(result,bPtrs[i]);
- }
- }
- for(i=0;i<aLength;i++) {
- int found=Logicset_LIST_CONTAINS(bPtrs,bLength,aPtrs[i]);
- if(!found) {
- resultlen++;
- Logicset_Add(result,aPtrs[i]);
- }
- }
- if(!resultlen) {
- Tcl_DecrRefCount(result);
- return NULL;
- }
- Tcl_Obj *resultPtr=Odie_ListObj_Sort(result);
- if(resultPtr!=result) {
- Tcl_DecrRefCount(result);
- }
- return resultPtr;
- }
- /* *Logicset_PRODUCT_MISSING */
- STUB_EXPORT Tcl_Obj *Logicset_PRODUCT_MISSING(Tcl_Obj *aset,Tcl_Obj *bset){
- int aLength;
- Tcl_Obj **aPtrs;
- if(!aset) {
- return NULL;
- }
- if(!bset) {
- return aset;
- }
- if(Tcl_ListObjGetElements(0, aset, &aLength, &aPtrs)) return bset;
- int bLength;
- Tcl_Obj **bPtrs;
- if(Tcl_ListObjGetElements(0, bset, &bLength, &bPtrs)) return aset;
- int i,resultlen=0;
- Tcl_Obj *result=Tcl_NewObj();
- for(i=0;i<aLength;i++) {
- int found=Logicset_LIST_CONTAINS(bPtrs,bLength,aPtrs[i]);
- if(!found) {
- resultlen++;
- Logicset_Add(result,aPtrs[i]);
- }
- }
- if(!resultlen) {
- Tcl_DecrRefCount(result);
- return NULL;
- }
- return result;
- }
- /* *Odie_ListObj_Sort */
- STUB_EXPORT Tcl_Obj *Odie_ListObj_Sort(Tcl_Obj *listObj){
- Tcl_Obj *resultPtr=NULL;
- int i, j, length, sortMode;
- int idx;
- Tcl_Obj **listObjPtrs, *indexPtr;
- SortElement *elementArray, *elementPtr;
- SortInfo sortInfo;
- sortInfo.isIncreasing = 1;
- sortInfo.sortMode = SORTMODE_DICTIONARY;
- sortInfo.indexv = NULL;
- sortInfo.unique = 1;
- sortInfo.interp = NULL;
- sortInfo.resultCode = TCL_OK;
- /*
- * The subList array below holds pointers to temporary lists built during
- * the merge sort. Element i of the array holds a list of length 2**i.
- */
- # define NUM_LISTS 30
- SortElement *subList[NUM_LISTS+1];
- sortInfo.resultCode = Tcl_ListObjGetElements(sortInfo.interp, listObj,
- &length, &listObjPtrs);
- if(length<2) {
- /*
- ** If the list is zero length, just return
- ** the original pointer
- */
- return listObj;
- }
- if (sortInfo.resultCode != TCL_OK || length <= 0) {
- goto done;
- }
- sortInfo.numElements = length;
- sortMode = sortInfo.sortMode;
- if ((sortMode == SORTMODE_ASCII_NC)
- || (sortMode == SORTMODE_DICTIONARY)) {
- /*
- * For this function's purpose all string-based modes are equivalent
- */
- sortMode = SORTMODE_ASCII;
- }
- /*
- * Initialize the sublists. After the following loop, subList[i] will
- * contain a sorted sublist of length 2**i. Use one extra subList at the
- * end, always at NULL, to indicate the end of the lists.
- */
- for (j=0 ; j<=NUM_LISTS ; j++) {
- subList[j] = NULL;
- }
- /*
- * The following loop creates a SortElement for each list element and
- * begins sorting it into the sublists as it appears.
- */
- elementArray = (SortElement *) Odie_Alloc( length * sizeof(SortElement));
- for (i=0; i < length; i++){
- idx = i;
- indexPtr = listObjPtrs[idx];
- sortInfo.resultCode=Odie_SortElement_FromObj(sortInfo.interp,sortMode,indexPtr,&elementArray[i]);
- if(sortInfo.resultCode!=TCL_OK) {
- goto done1;
- }
- }
- for (i=0; i < length; i++){
- /*
- * Merge this element in the pre-existing sublists (and merge together
- * sublists when we have two of the same size).
- */
- elementArray[i].nextPtr = NULL;
- elementPtr = &elementArray[i];
- for (j=0 ; subList[j] ; j++) {
- elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
- subList[j] = NULL;
- }
- if (j >= NUM_LISTS) {
- j = NUM_LISTS-1;
- }
- subList[j] = elementPtr;
- }
- /*
- * Merge all sublists
- */
- elementPtr = subList[0];
- for (j=1 ; j<NUM_LISTS ; j++) {
- elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
- }
- /*
- * Now store the sorted elements in the result list.
- */
- if (sortInfo.resultCode == TCL_OK) {
- resultPtr=Odie_MergeList_ToObj(elementPtr);
- }
- done1:
- Odie_Free((char *) elementArray);
- done:
- if (sortInfo.sortMode == SORTMODE_COMMAND) {
- Tcl_DecrRefCount(sortInfo.compareCmdPtr);
- Tcl_DecrRefCount(listObj);
- sortInfo.compareCmdPtr = NULL;
- }
- if (sortInfo.resultCode != TCL_OK) {
- return NULL;
- }
- return resultPtr;
- }
- /* Odie_Trace */
- int Odie_Trace(int newvalue){
- OdieTrace=newvalue;
- return OdieTrace;
- }
- /* *Odie_LiteralConstantObj */
- Tcl_Obj *Odie_LiteralConstantObj(int which){
- if(which > ODIE_STATIC_MAX || which < 0) {
- Tcl_IncrRefCount(OdieStatic[ODIE_STATIC_NULL]);
- return OdieStatic[ODIE_STATIC_NULL];
- }
- Tcl_IncrRefCount(OdieStatic[which]);
- return OdieStatic[which];
- }
- /* *Odie_StoreObj */
- Tcl_Obj *Odie_StoreObj(Tcl_Obj *value){
- Tcl_Obj *storedVal;
- double floatVal;
- int intVal,strLen;
- char *stringVal,*strtmp;
- if(!value) {
- storedVal=OdieStatic[ODIE_STATIC_NULL];
- Tcl_IncrRefCount(storedVal);
- nOdieDictSpecNull++;
- return storedVal;
- }
- /* If this value is already shared, just store it and bump the refcount */
- if(Tcl_IsShared(value)) {
- Tcl_IncrRefCount(value);
- nOdieDictSpecRecycled++;
- return value;
- }
- /* Try to map this string to an existing literal */
- stringVal=Tcl_GetString(value);
- storedVal=Odie_constant(stringVal,0);
- if(storedVal) {
- Tcl_IncrRefCount(storedVal);
- nOdieDictSpecShared++;
- return storedVal;
- }
- /* Avoid storing a list or other volitile data */
- strtmp=strchr(stringVal,' ');
- if(!strtmp) {
- strtmp=strchr(stringVal,'/');
- if(!strtmp) {
- storedVal=Odie_constant(stringVal,1);
- Tcl_IncrRefCount(storedVal);
- return storedVal;
- }
- }
- Tcl_IncrRefCount(value);
- return value;
- }
- /* *Odie_constant */
- static Tcl_Obj *Odie_constant(const char *zName,int create){
- int len,isNew=0;
- Tcl_HashEntry *pEntry;
- Tcl_Obj *p;
- if(zName==NULL) {
- return NULL;
- }
- if(create) {
- pEntry=Tcl_CreateHashEntry(&OdieLiteralStringTable,zName,&isNew);
- } else {
- pEntry=Tcl_FindHashEntry(&OdieLiteralStringTable,zName);
- }
- if(isNew) {
- nOdieObjString++;
- len = strlen(zName);
- p=Tcl_NewStringObj(zName,len);
- Tcl_IncrRefCount(p);
- Tcl_SetHashValue(pEntry,(ClientData)p);
- return p;
- }
- if(pEntry) {
- p=(Tcl_Obj*)Tcl_GetHashValue(pEntry);
- return p;
- }
- return NULL;
- }
- /* Odie_SameString */
- int Odie_SameString(char *aPtr,char *bPtr){
- if(aPtr==bPtr) {
- return 1;
- }
- if(!bPtr || !aPtr) {
- return 0;
- }
- if(strcmp(aPtr,bPtr)==0) {
- return 1;
- }
- return 0;
- }
- /* *Odie_LiteralString */
- char *Odie_LiteralString(const char *zName){
- Tcl_Obj *p;
- p=Odie_constant(zName,1);
- return Tcl_GetString(p);
- }
- /* *Odie_LiteralStringObj */
- Tcl_Obj *Odie_LiteralStringObj(const char *zName){
- Tcl_Obj *p;
- p=Odie_constant(zName,1);
- Tcl_IncrRefCount(p);
- return p;
- }
- /* Odie_DictObjPut */
- inline extern int Odie_DictObjPut(Tcl_Interp *interp,Tcl_Obj *pDictObj,const char *pField,Tcl_Obj *pValue){
- int result=TCL_OK;
- if(!pValue) {
- return TCL_OK;
- }
- result=Tcl_DictObjPut(interp,pDictObj,Odie_LiteralStringObj(pField),pValue);
- return result;
- }
- /* *Odie_HashGet */
- Tcl_Obj *Odie_HashGet(Tcl_HashTable *localDict,char *fieldStr){
- Tcl_Obj *valuePtr;
- Tcl_HashEntry *i;
- if(!localDict) {
- return NULL;
- }
- i=Tcl_FindHashEntry(localDict,fieldStr);
- if(!i) {
- return NULL;
- }
- valuePtr=(Tcl_Obj*)Tcl_GetHashValue(i);
- if(!valuePtr) {
- return NULL;
- }
- nOdieDictSpecAccessed++;
- Tcl_IncrRefCount(valuePtr);
- return valuePtr;
- }
- /* Odie_HashPut */
- void Odie_HashPut(Tcl_HashTable **infoDictPtr,const char *key,Tcl_Obj *value){
- Tcl_HashTable *result=*infoDictPtr;
- Tcl_HashEntry *pEntry;
- Tcl_Obj *valuePtr;
- int isNew=0;
- int delete=0,len=0;
- char *valueStr;
- if(value==NULL) {
- delete=1;
- }
- valueStr=Tcl_GetString(value);
- len=strlen(valueStr);
- if(len==0) {
- delete=1;
- }
- if(!result && delete) {
- return;
- }
- if(!result) {
- result=(Tcl_HashTable*)Odie_Alloc( sizeof(Tcl_HashTable) );
- Tcl_InitHashTable(result,TCL_STRING_KEYS);
- nOdieHashTable++;
- nOdieHashTableCreated++;
- *infoDictPtr=result;
- }
- if(delete) {
- /* If we were given a null or an empty string, delete */
- pEntry=Tcl_FindHashEntry(result,key);
- if(!pEntry) return;
- nOdieDictSpecDeleted++;
- nOdieDictSpecCount--;
- valuePtr=(Tcl_Obj*)Tcl_GetHashValue(pEntry);
- Tcl_DecrRefCount(valuePtr);
- Tcl_DeleteHashEntry(pEntry);
- return;
- }
- pEntry=Tcl_CreateHashEntry(result,Odie_LiteralString(key),&isNew);
- if(!isNew) {
- valuePtr=(Tcl_Obj*)Tcl_GetHashValue(pEntry);
- nOdieDictSpecModified++;
- Tcl_DecrRefCount(valuePtr);
- } else {
- nOdieDictSpecCreated++;
- nOdieDictSpecCount++;
- }
- valuePtr=Odie_StoreObj(value);
- Tcl_SetHashValue(pEntry,valuePtr);
- return;
- }
- /* Odie_HashFree */
- void Odie_HashFree(Tcl_HashTable **infoDictPtr){
- if(*infoDictPtr) {
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- Tcl_HashTable *ptr=*infoDictPtr;
- for(i=Tcl_FirstHashEntry(ptr,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Tcl_Obj *valuePtr=(Tcl_Obj *)Tcl_GetHashValue(i);
- Tcl_DecrRefCount(valuePtr);
- nOdieDictSpecCount--;
- nOdieDictSpecDeleted++;
- }
- nOdieHashTableDeleted++;
- nOdieHashTable--;
- Tcl_DeleteHashTable(ptr);
- Tcl_Free((char*)ptr);
- }
- *infoDictPtr=NULL;
- }
- /* Odie_constant_inject */
- static void Odie_constant_inject(Tcl_Obj *value){
- int len,isNew=0;
- char *zName=Tcl_GetString(value);
- Tcl_HashEntry *pEntry;
- pEntry=Tcl_CreateHashEntry(&OdieLiteralStringTable,zName,&isNew);
- if(isNew) {
- nOdieObjString++;
- Tcl_IncrRefCount(value);
- Tcl_SetHashValue(pEntry,(ClientData)value);
- }
- }
- /* Odie_RoidFromString */
- Roid Odie_RoidFromString(char *idstring,short charcode){
- char prefix[32];
- int id;
- int result;
- if(!idstring) {
- return -1;
- }
- result=sscanf(idstring,"%d",&id);
- if(result>0) {
- return id;
- }
- result=sscanf(idstring,"%c%d",prefix,&id);
- if(result>0) {
- return id;
- }
- return -1;
- }
- /* *Irm_NewLocationObj */
- Tcl_Obj *Irm_NewLocationObj(Irm_Location *loc){
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(NULL, pResult, Odie_LiteralIntObj(loc->deckid));
- Tcl_ListObjAppendElement(NULL, pResult, Tcl_NewIntObj(loc->x));
- Tcl_ListObjAppendElement(NULL, pResult, Tcl_NewIntObj(loc->y));
- return pResult;
- }
- /* Location_FromName */
- int Location_FromName(char *stringVal,int *did,double *x,double *y,double *z){
- /*
- ** Obtain location from name
- */
- #ifdef build_IRM
- int deckid=0;
- char type=0;
- int roid;
- int found=0;
- int result=sscanf(stringVal,"%c%d-%d",&type,&roid,&deckid);
- #endif
- Irm_Location temp;
- temp.deckid=0;
- temp.x=0;
- temp.y=0;
- #ifdef build_IRM
- if(result==2 || result==3) {
- switch(type) {
- case 'c': {
- if(CrewRoute_ComptCenter(roid,deckid,&temp)) {
- if(deckid) {
- temp.deckid=deckid;
- } else {
- temp.deckid=1;
- }
- temp.x=0;
- temp.y=0;
- }
- found=1;
- break;
- }
- case 'e': {
- SimNode *pDest=SimNode_ById(roid,0);
- if(pDest) {
- SimNode_StructLocation(&temp,pDest);
- found=1;
- }
- break;
- }
- case 'p': {
- Portal *pDest=Portal_ById(roid,0);
- if(pDest) {
- Portal_StructLocation(&temp,pDest);
- found=1;
- }
- break;
- }
- case 'v': {
- Crew *pDest=Crew_ById(roid,0);
- if(pDest) {
- Crew_StructLocation(&temp,pDest);
- found=1;
- }
- break;
- }
- }
- }
- if (!found) {
- Entity *pDest=Entity_ByName(stringVal,0);
- if(!pDest) {
- return TCL_ERROR;
- }
- Entity_StructLocation(&temp,pDest);
- }
- #else
- Entity *pDest=Entity_ByName(stringVal,0);
- if(!pDest) {
- return TCL_ERROR;
- }
- Entity_StructLocation(&temp,pDest);
- #endif
- *did=temp.deckid;
- *x=temp.x;
- *y=temp.y;
- *z=temp.zoff;
- return TCL_OK;
- }
- /* Location_FromTclObj */
- int Location_FromTclObj(Tcl_Interp *interp, Tcl_Obj *pList,int *did,double *x,double *y){
- int listlen;
- Tcl_Obj **elist;
- double z;
- if(Tcl_ListObjGetElements(interp,pList,&listlen,&elist)) {
- return TCL_ERROR;
- }
- if(listlen == 1) {
- /*
- ** Obtain location from name
- */
- char *stringVal=Tcl_GetString(pList);
- if (Location_FromName(stringVal,did,x,y,&z)) {
- Tcl_AppendResult(interp, "Unknown entity ", stringVal, 0);
- return TCL_ERROR;
- }
- return TCL_OK;
- }
- if(listlen < 3 || listlen > 4) {
- Tcl_AppendResult(interp, "Could not interpret location ", Tcl_GetString(pList), 0);
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, elist[0], did) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, elist[1], x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, elist[2], y) ) return TCL_ERROR;
- return TCL_OK;
- }
- /* Location_Base_FromTclObj */
- int Location_Base_FromTclObj(Tcl_Interp *interp, Tcl_Obj *pList,int *did,double *x,double *y,double *z){
- int listlen;
- Tcl_Obj **elist;
- if(Tcl_ListObjGetElements(interp,pList,&listlen,&elist)) {
- return TCL_ERROR;
- }
- if(listlen == 1) {
- /*
- ** Obtain location from name
- */
- char *stringVal=Tcl_GetString(pList);
- if (Location_FromName(stringVal,did,x,y,z)) {
- Tcl_AppendResult(interp, "Unknown entity ", stringVal, 0);
- return TCL_ERROR;
- }
- return TCL_OK;
- }
- if(listlen < 3 || listlen > 4) {
- Tcl_AppendResult(interp, "Could not interpret location ", Tcl_GetString(pList), 0);
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, elist[0], did) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, elist[1], x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, elist[2], y) ) return TCL_ERROR;
- *z=0.0;
- if(listlen==4) {
- if( Tcl_GetDoubleFromObj(interp, elist[3], z) ) return TCL_ERROR;
- }
- return TCL_OK;
- }
- /* location_match */
- int location_match(Irm_Location *a,Irm_Location *b,int tolerance){
- /*
- ** Returns a 0 if the two points are "close enough"
- */
- int d;
- if(a==b) {
- return 1;
- }
- if(a->deckid!=b->deckid) {
- return 0;
- }
- d=a->x - b->x;
- if(d<-tolerance||d>tolerance) {
- return 0;
- }
- d=a->y - b->y;
- if(d<-tolerance||d>tolerance) {
- return 0;
- }
- return 1;
- }
- /* irm_gridhash_decompose */
- void irm_gridhash_decompose(Tcl_WideInt gridhash,int *style,int *rdeckid,int *rgx,int *rgy){
- Tcl_WideInt mask;
- int gy,gx,deckid;
- int isHex=0;
- /* Unpack the coordinates */
- mask=gridhash;
- gx=mask & 0xFFFF;
- if(gx & 0x8000) {
- /* Restore negative */
- gx-=0xffff;
- gx--;
- }
- mask>>=16;
- gy=mask & 0xFFF;
- if(gy & 0x800) {
- /* Restore negative */
- gy-=0xfff;
- gy--;
- }
- mask>>=12;
- deckid=mask & 0x3F;
- mask>>=6;
- isHex=mask;
- *style=isHex;
- *rdeckid=deckid;
- *rgx=gx;
- *rgy=gy;
- }
- /* irm_gridhash_compose */
- Tcl_WideInt irm_gridhash_compose (int style,int deckid,int gx,int gy){
- Tcl_WideInt result;
- result=(style&1);
- result<<=6;
- /* Encode the coordinate packed into a 32 bit integer */
- result|=(0x3F & deckid);
- result<<=12;
- result|=(0xFFF & gy);
- result<<=16;
- result|=(0xFFFF & gx);
- return result;
- }
- /* irm_squaregrid_hash */
- Tcl_WideInt irm_squaregrid_hash(int grid,int deckid,int x,int y){
- int gx,gy;
- gy=(int)round(y/grid);
- gx=(int)round(x/grid);
- return irm_gridhash_compose(0,deckid,gx,gy);
- }
- /* irm_hexgrid_hash */
- Tcl_WideInt irm_hexgrid_hash(int grid,int deckid,int x,int y){
- int gx,gy;
- gy=(int)round(y/grid);
- if(abs(gy)%2==1){
- gx=(int)round((x-grid/2)/grid);
- } else {
- gx=(int)round(x/grid);
- }
- return irm_gridhash_compose(1,deckid,gx,gy);
- }
- /* irm_gridhash_location */
- void irm_gridhash_location(Irm_Location *lPtr,Tcl_WideInt gridhash,int gridsize){
- int gy,gx,deckid;
- int isHex=0;
- irm_gridhash_decompose(gridhash,&isHex,&deckid,&gx,&gy);
- lPtr->deckid=deckid;
- lPtr->y=gy*gridsize;
- if(isHex) {
- if(abs(gy)%2==1) {
- lPtr->x=gx*gridsize+(gridsize/2);
- } else {
- lPtr->x=gx*gridsize;
- }
- } else {
- lPtr->x=gx*gridsize;
- }
- }
- /* Simulator_Init */
- void Simulator_Init(Simulator *p){}
- /* Simulator_Reset */
- void Simulator_Reset(Simulator *p){}
- /* Structure Entity */
- const struct OdieParamNameMap Entity_paramNameMap[] = {
- { "active", CSTRUCT_ENTITY_ACTIVE, PTYPE_INT },
- { "changed", CSTRUCT_ENTITY_CHANGED, PTYPE_INT },
- { "class", CSTRUCT_ENTITY_CLASS, PTYPE_FLOAT },
- { "drawn", CSTRUCT_ENTITY_DRAWN, PTYPE_INT },
- { "groupid", CSTRUCT_ENTITY_GROUPID, PTYPE_INT },
- { "hidden", CSTRUCT_ENTITY_HIDDEN, PTYPE_INT },
- { "highlight", CSTRUCT_ENTITY_HIGHLIGHT, PTYPE_INT },
- { "is_type", CSTRUCT_ENTITY_IS_TYPE, PTYPE_INT },
- { "moved", CSTRUCT_ENTITY_MOVED, PTYPE_INT },
- { "nchild", CSTRUCT_ENTITY_NCHILD, PTYPE_INT },
- { "oncount", CSTRUCT_ENTITY_ONCOUNT, PTYPE_INT },
- { "open", CSTRUCT_ENTITY_OPEN, PTYPE_INT },
- { "parent", CSTRUCT_ENTITY_PARENT, PTYPE_INT },
- { "redraw", CSTRUCT_ENTITY_REDRAW, PTYPE_INT },
- { "repaint", CSTRUCT_ENTITY_REPAINT, PTYPE_INT },
- { "synthetic", CSTRUCT_ENTITY_SYNTHETIC, PTYPE_INT },
- { "trace", CSTRUCT_ENTITY_TRACE, PTYPE_INT },
- { "visible", CSTRUCT_ENTITY_VISIBLE, PTYPE_INT },
- };
- const struct OdieParamNameMap Entity_canonicalNameMap[] = {
- { "active", CSTRUCT_ENTITY_ACTIVE, PTYPE_INT },
- { "changed", CSTRUCT_ENTITY_CHANGED, PTYPE_INT },
- { "class", CSTRUCT_ENTITY_CLASS, PTYPE_FLOAT },
- { "drawn", CSTRUCT_ENTITY_DRAWN, PTYPE_INT },
- { "groupid", CSTRUCT_ENTITY_GROUPID, PTYPE_INT },
- { "hidden", CSTRUCT_ENTITY_HIDDEN, PTYPE_INT },
- { "highlight", CSTRUCT_ENTITY_HIGHLIGHT, PTYPE_INT },
- { "is_type", CSTRUCT_ENTITY_IS_TYPE, PTYPE_INT },
- { "moved", CSTRUCT_ENTITY_MOVED, PTYPE_INT },
- { "nchild", CSTRUCT_ENTITY_NCHILD, PTYPE_INT },
- { "oncount", CSTRUCT_ENTITY_ONCOUNT, PTYPE_INT },
- { "open", CSTRUCT_ENTITY_OPEN, PTYPE_INT },
- { "parent", CSTRUCT_ENTITY_PARENT, PTYPE_INT },
- { "redraw", CSTRUCT_ENTITY_REDRAW, PTYPE_INT },
- { "repaint", CSTRUCT_ENTITY_REPAINT, PTYPE_INT },
- { "synthetic", CSTRUCT_ENTITY_SYNTHETIC, PTYPE_INT },
- { "trace", CSTRUCT_ENTITY_TRACE, PTYPE_INT },
- { "visible", CSTRUCT_ENTITY_VISIBLE, PTYPE_INT },
- };
- #include <math.h>
- #include <string.h>
- #define ENTITY_SEARCH_NCOUNT 15
- static const char *ENTITY_SEARCH_strs[] = {
- "active",
- "class",
- "comptid",
- "deckid",
- "drawn",
- "groupid",
- "hidden",
- "highlight",
- "moved",
- "redraw",
- "repaint",
- "synthetic",
- "trace",
- "typeid",
- "visible",
- 0
- };
- enum ENTITY_SEARCH_enum {
- ENTITY_SEARCH_ACTIVE,
- ENTITY_SEARCH_CLASS,
- ENTITY_SEARCH_COMPTID,
- ENTITY_SEARCH_DECKID,
- ENTITY_SEARCH_DRAWN,
- ENTITY_SEARCH_GROUPID,
- ENTITY_SEARCH_HIDDEN,
- ENTITY_SEARCH_HIGHLIGHT,
- ENTITY_SEARCH_MOVED,
- ENTITY_SEARCH_REDRAW,
- ENTITY_SEARCH_REPAINT,
- ENTITY_SEARCH_SYNTHETIC,
- ENTITY_SEARCH_TRACE,
- ENTITY_SEARCH_TYPEID,
- ENTITY_SEARCH_VISIBLE
- };
- /* SimType_Walk_Parent */
- int SimType_Walk_Parent(Entity *p){
- /*
- ** Subroutine to decend into children of a simtype
- */
- Entity *parent;
- if(!p) {
- return 0;
- }
- if(p->public_hidden) {
- return -1;
- }
- if(p->public_active==2) {
- return -1;
- }
- if(p->public_active==1) {
- return 1;
- }
- if(p->public_visible) {
- return 1;
- }
- if(p->public_parent) {
- parent=SimType_ById(p->public_parent,0);
- if(parent) {
- return SimType_Walk_Parent(parent);
- }
- }
- return 0;
- }
- /* *Entity_ById */
- Entity *Entity_ById(char prefix,Roid id,int createFlag){
- Entity *p;
- char zName[32];
- sprintf(zName, "%c%d", prefix, id);
- p=Entity_ByName(zName,createFlag);
- if(createFlag) {
- if(!p->id) {
- p->id=id;
- }
- }
- return p;
- }
- /* *Entity_ByName */
- Entity *Entity_ByName(const char *zName,int createFlag){
- Tcl_HashEntry *pEntry;
- assert( zName!=0 );
- if(CurrentSim->GlobalSim) {
- pEntry=Tcl_FindHashEntry(&CurrentSim->GlobalSim->EntityIdSet,zName);
- } else {
- pEntry=Tcl_FindHashEntry(&CurrentSim->EntityIdSet,zName);
- }
- if(pEntry) {
- return (Entity*)Tcl_GetHashValue(pEntry);
- }
- if(createFlag) {
- return EntityCreate(zName);
- }
- return NULL;
- }
- /* *Entity_ExportField */
- Tcl_Obj *Entity_ExportField(Entity *e,Tcl_HashTable *local,char *field,int nullcode){
- Tcl_Obj *result=Entity_GetField(e,local,field);
- if(result) {
- return result;
- }
- if(nullcode==ODIE_NULL_ZERO) {
- return Tcl_NewBooleanObj(0);
- }
- if(nullcode==ODIE_NULL_EMPTY) {
- return Tcl_NewObj();
- }
- return NULL;
- }
- /* *Entity_First */
- Tcl_HashEntry *Entity_First(Simulator *sim,Tcl_HashSearch *search){
- if(sim->GlobalSim) {
- return Tcl_FirstHashEntry(&sim->GlobalSim->EntityIdSet,search);
- } else {
- return Tcl_FirstHashEntry(&sim->EntityIdSet,search);
- }
- }
- /* *Entity_GetDict */
- Tcl_Obj *Entity_GetDict(Entity *e,Tcl_HashTable *local){
- Tcl_HashTable *localDict=NULL;
- Tcl_Obj *pResult=NULL;
- Entity *p=NULL;
- Entity *pStack[10];
- int i,count=-1;
- p=e;
- while(p && count<10) {
- count++;
- pStack[count]=p;
- p=p->pType;
- }
- /*
- ** Add the minimum specs for the class
- */
- for(i=count;i>=0;i--) {
- p=pStack[i];
- localDict=p->infoDict;
- if(localDict) {
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- for(i=Tcl_FirstHashEntry(localDict,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- if(!pResult) pResult=Tcl_NewDictObj();
- Odie_DictObjPut(0,pResult,Tcl_GetHashKey(localDict,i),Tcl_GetHashValue(i));
- }
- }
- }
- localDict=local;
- if(localDict) {
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- for(i=Tcl_FirstHashEntry(localDict,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- if(!pResult) pResult=Tcl_NewDictObj();
- Odie_DictObjPut(0,pResult,Tcl_GetHashKey(localDict,i),Tcl_GetHashValue(i));
- }
- }
- return pResult;
- }
- /* *Entity_GetField */
- Tcl_Obj *Entity_GetField(Entity *e,Tcl_HashTable *local,char *field){
- Tcl_Obj *result=NULL;
- Entity *p=NULL;
- result=Odie_HashGet(local,field);
- if(result) {
- return result;
- }
- p=e;
- while(p) {
- result=Odie_HashGet(p->infoDict,field);
- if(result) {
- return result;
- }
- if(p) p=p->pType;
- }
- return NULL;
- }
- /* *Entity_GroupToTclObj */
- Tcl_Obj *Entity_GroupToTclObj(Entity *pNode){
- Roid groupid;
- if(!pNode) {
- return Tcl_NewBooleanObj(0);
- }
- groupid=Entity_StructGetGroup(pNode);
- if(!groupid) {
- return Tcl_NewBooleanObj(0);
- }
- return Irm_NewRoidObj(groupid);
- }
- /* *Entity_Identify */
- Tcl_Obj *Entity_Identify(Entity *pNode){
- if(!pNode) {
- return Tcl_NewObj();
- }
- if(pNode->public_is_type) {
- return Irm_NewRoidObj(pNode->id);
- }
- if(pNode->name!=NULL) {
- return Odie_LiteralStringObj(pNode->name);
- } else {
- return Irm_NewRoidObj(pNode->id);
- }
- }
- /* *Entity_IdentifyCompartment */
- Entity *Entity_IdentifyCompartment(Tcl_Obj *entryPtr){
- Entity *comptPtr=NULL;
- int intval;
- if(entryPtr==NULL) {
- return NULL;
- }
- if(Tcl_GetIntFromObj(NULL,entryPtr,&intval)==TCL_OK) {
- if(intval<=0) {
- return NULL;
- }
- comptPtr=Entity_ById('c',intval,0);
- } else {
- comptPtr=Entity_ByName(Tcl_GetString(entryPtr),0);
- }
- return comptPtr;
- }
- /* *Entity_PublicId */
- Tcl_Obj *Entity_PublicId(Entity *pNode){
- char idstring[64];
- if(!pNode) {
- return Irm_NewRoidObj(0);
- }
- if(pNode->pType) {
- if(pNode->pType->name!=NULL) {
- return Odie_LiteralStringObj(pNode->pType->name);
- }
- }
- sprintf(idstring,"%d",pNode->id);
- return Odie_LiteralStringObj(idstring);
- }
- /* *Entity_SpecHashGet */
- Tcl_Obj *Entity_SpecHashGet(Entity *p,Tcl_Obj* key,int nulltype){
- return Entity_ExportField(p->pType,p->infoDict,Tcl_GetString(key),nulltype);
- }
- /* *Entity_StructGet */
- Tcl_Obj *Entity_StructGet(Entity *pNode,int field){
- switch (field) {
- case CSTRUCT_ENTITY_HIDDEN: return Odie_LiteralIntObj(pNode->public_hidden);
- case CSTRUCT_ENTITY_IS_TYPE: return Odie_LiteralIntObj(pNode->public_is_type);
- case CSTRUCT_ENTITY_REDRAW: return Odie_LiteralIntObj(pNode->public_redraw);
- case CSTRUCT_ENTITY_ACTIVE: return Odie_LiteralIntObj(pNode->public_active);
- case CSTRUCT_ENTITY_GROUPID: return Irm_NewRoidObj(pNode->public_groupid);
- case CSTRUCT_ENTITY_TRACE: return Odie_LiteralIntObj(pNode->public_trace);
- case CSTRUCT_ENTITY_REPAINT: return Odie_LiteralIntObj(pNode->public_repaint);
- case CSTRUCT_ENTITY_VISIBLE: return Odie_LiteralIntObj(pNode->public_visible);
- case CSTRUCT_ENTITY_MOVED: return Odie_LiteralIntObj(pNode->public_moved);
- case CSTRUCT_ENTITY_CHANGED: return Odie_LiteralIntObj(pNode->public_changed);
- case CSTRUCT_ENTITY_OPEN: return Odie_LiteralIntObj(pNode->public_open);
- case CSTRUCT_ENTITY_CLASS: {
- char zBuf[2];
- zBuf[0]=pNode->public_class;
- zBuf[1]=0;
- return Odie_LiteralStringObj(zBuf);
- }
- case CSTRUCT_ENTITY_PARENT: return Irm_NewRoidObj(pNode->public_parent);
- case CSTRUCT_ENTITY_SYNTHETIC: return Odie_LiteralIntObj(pNode->public_synthetic);
- case CSTRUCT_ENTITY_HIGHLIGHT: return Odie_LiteralIntObj(pNode->public_highlight);
- case CSTRUCT_ENTITY_DRAWN: return Odie_LiteralIntObj(pNode->public_drawn);
- case CSTRUCT_ENTITY_NCHILD: return Odie_LiteralIntObj(pNode->public_nchild);
- case CSTRUCT_ENTITY_ONCOUNT: return Odie_LiteralIntObj(pNode->public_oncount);
- }
- return NULL;
- }
- /* *Entity_StructGetType */
- Entity *Entity_StructGetType(Entity *p){
- return p->pType;
- }
- /* *Entity_StructToDict */
- Tcl_Obj *Entity_StructToDict(Tcl_Interp *interp,Entity *p,int virtual){
- Tcl_Obj *pResult=NULL;
- int i;
- if(virtual) {
- pResult=Entity_GetDict(p->pType,p->infoDict);
- }
- if(!pResult) {
- pResult=Tcl_NewObj();
- }
- /* Finaly, Add the Tcl Data */
- for(i=0;i<CSTRUCT_ENTITY_Count;i++) {
- Tcl_Obj *newElement=Entity_StructGet(p,i);
- Odie_DictObjPut(interp,pResult,Entity_paramNameMap[i].zName,newElement);
- }
- if(virtual) {
- Entity_StructAddLocation(interp,p,pResult);
- }
- return pResult;
- }
- /* *Entity_StructTypeIdToTclObj */
- Tcl_Obj *Entity_StructTypeIdToTclObj(Entity *pNode){
- if(!pNode) {
- return Irm_NewRoidObj(0);
- }
- if(!pNode->pType) {
- return Irm_NewRoidObj(0);
- }
- return Irm_NewRoidObj(pNode->pType->id);
- }
- /* *Entity_TypeToTclObj */
- Tcl_Obj *Entity_TypeToTclObj(Entity *pNode){
- Entity *pType;
- if(!pNode) {
- return Tcl_NewBooleanObj(0);
- }
- pType=Entity_StructGetType(pNode);
- if(!pType) {
- return Tcl_NewBooleanObj(0);
- }
- return Irm_NewRoidObj(pType->id);
- }
- /* *EntityCreate */
- Entity *EntityCreate(const char *zName){
- int len,isNew;
- Tcl_HashEntry *pEntry;
- Entity *p;
- if(CurrentSim->GlobalSim) {
- pEntry = Tcl_CreateHashEntry(&CurrentSim->GlobalSim->EntityIdSet, zName, &isNew);
- } else {
- pEntry = Tcl_CreateHashEntry(&CurrentSim->EntityIdSet, zName, &isNew);
- }
- if(isNew) {
- len = strlen(zName);
- p = (Entity *)Odie_Alloc( sizeof(*p)+len+1 );
- strcpy(p->name, zName);
- p->public_class=zName[0];
- Entity_StructAlloc(p);
- Tcl_SetHashValue(pEntry,(ClientData)p);
- return p;
- }
- if(pEntry) {
- p=(Entity *)Tcl_GetHashValue(pEntry);
- return p;
- }
- return NULL;
- }
- /* Entity_ApplySettings */
- void Entity_ApplySettings(Entity *pNode){
- if(pNode->public_class=='e') {
- Tcl_Obj *comptidObj=Entity_GetField(NULL,pNode->infoDict,"comptid");
- if(comptidObj) {
- /*
- ** If a local spec for "comptid" is given, use that
- ** as an implied "comptdid" statement
- */
- pNode->comptPtr=Entity_IdentifyCompartment(comptidObj);
- }
- }
- }
- /* Entity_BuildMatch */
- int Entity_BuildMatch(Tcl_Interp *interp,Tcl_Obj *matchvar,int *matchStruct){
- int llength,idx;
- /*
- ** Default to universal match
- */
- for(idx=0;idx<ENTITY_SEARCH_NCOUNT;idx++) {
- matchStruct[idx]=-1;
- }
- /* Handle a null */
- if(!matchvar) {
- return TCL_OK;
- }
- if( Tcl_ListObjLength(interp, matchvar, &llength) ) return TCL_ERROR;
- if( llength%2!=0 ){
- Tcl_AppendResult(interp, "Search params must be a key/value list "
- "valid keys: visible hidden class redraw highlighted", 0);
- return TCL_ERROR;
- }
- for(idx=0; idx<llength-1; idx+=2){
- int field;
- int value;
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, matchvar, idx, &pObj);
- if( Tcl_GetIndexFromObj(interp, pObj, ENTITY_SEARCH_strs, "option", 0, &field) ){
- return TCL_ERROR;
- }
- Tcl_ListObjIndex(0, matchvar, idx+1, &pObj);
- if(field==ENTITY_SEARCH_CLASS) {
- char *str,prefix;
- str=Tcl_GetString(pObj);
- if(str) {
- prefix=str[0];
- matchStruct[field]=prefix;
- }
- } else {
- if(Tcl_GetIntFromObj(interp, pObj, &value)) {
- return TCL_ERROR;
- }
- matchStruct[field]=value;
- }
- }
- return TCL_OK;
- }
- /* Entity_Delete */
- void Entity_Delete(Entity *p){
- Entity_StructFree(p);
- Odie_Free((char *)p);
- }
- /* Entity_FromTclObj */
- int Entity_FromTclObj(Tcl_Interp *interp, Tcl_Obj *pObj, Entity **ppEntity){
- *ppEntity = NULL;
- int i;
- if( Tcl_GetIntFromObj(interp, pObj, &i) == TCL_OK ) {
- *ppEntity = SimType_ById(i, 0);
- if(*ppEntity) {
- return TCL_OK;
- }
- }
- Tcl_ResetResult(interp);
- *ppEntity = Entity_ByName(Tcl_GetString(pObj),0);
- if( *ppEntity==0 ){
- Tcl_AppendResult(interp, "no such entity: ",
- Tcl_GetString(pObj), 0);
- return TCL_ERROR;
- }
- return TCL_OK;
- }
- /* Entity_Module_Advance */
- void Entity_Module_Advance(Simulator *ActiveSim,int clocktime){
- /* Default empty implementation */
- }
- /* Entity_Module_Free */
- void Entity_Module_Free(Simulator *sim){
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- if(!sim->module_entity) return;
- for(i=Entity_First(sim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- Entity_StructFree(p);
- Odie_Free((char *)p);
- }
- for(i=SimType_First(sim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- Entity_StructFree(p);
- Odie_Free((char *)p);
- }
- Tcl_DeleteHashTable(&sim->EntityIdSet);
- Tcl_DeleteHashTable(&sim->SimTypeIdSet);
- sim->module_entity=0;
- }
- /* Entity_Module_Init */
- void Entity_Module_Init(Simulator *sim){}
- /* Entity_Module_Rewind */
- void Entity_Module_Rewind(Simulator *sim){
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- if(!sim->module_entity) return;
- for(i=Entity_First(sim,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_redraw=1;
- p->public_repaint=1;
- }
- }
- /* Entity_Node_ApplyLocation */
- void Entity_Node_ApplyLocation(Entity *pNode){
- #ifdef build_IRM
- Entity *comptPtr;
- int cid,sid,c;
- c=CrewrouteSubcompartmentAt(pNode->x,pNode->y,pNode->deckid,&sid,&cid,NULL,NULL);
- comptPtr=Entity_ById('c',c,0);
- pNode->public_moved=1;
- if(comptPtr) {
- pNode->comptPtr=comptPtr;
- } else {
- pNode->comptPtr=NULL;
- }
- #endif
- }
- /* Entity_Node_GetLink */
- void Entity_Node_GetLink(Tcl_Obj *pResult,Entity *pNode,char *linktype){}
- /* Entity_nodeeval */
- int Entity_nodeeval(Tcl_Interp *interp,Entity *p,Tcl_Obj *body,int writeback){
- Tcl_Obj *id;
- int i,len;
- Tcl_Obj *varv[CSTRUCT_ENTITY_Count*2];
- int result;
- Entity_StructWith(interp,p,1,varv);
- id=Entity_Identify(p);
- Tcl_ObjSetVar2(interp,Odie_LiteralStringObj("id"),NULL,id,0);
- Tcl_ObjSetVar2(interp,Odie_LiteralStringObj("typeid"),NULL,Entity_TypeToTclObj(p),0);
- Tcl_ObjSetVar2(interp,Odie_LiteralStringObj("groupid"),NULL,Entity_GroupToTclObj(p),0);
- /*
- for(i=0;i<CSTRUCT_ENTITY_Count*2;i++) {
- Tcl_IncrRefCount(varv[i]);
- }
- */
- result=Tcl_EvalObjEx(interp, body, 0);
- if(result!=TCL_OK) {
- return result;
- }
- if(writeback){
- /*
- ** Read values back into the dict
- ** For now, we limit writeback to state variables
- ** And we don't care about garbage values
- */
- int changed=0;
- for(i=0;i<CSTRUCT_ENTITY_Count*2;i+=2) {
- Tcl_Obj *newValue;
- int offset;
- int type;
- newValue=Tcl_ObjGetVar2(interp,varv[i],(Tcl_Obj*)NULL,0);
- if(newValue==varv[i+1]) {
- /* Undocumented, unsanctioned, but it works in practice
- ** If the pointer hasn't changed, neither has the value
- */
- continue;
- }
- if(!newValue) {
- /* Variable must have been unset... move along */
- continue;
- }
- if( Entity_StructValueOffset(0, varv[i], &offset, &type) == TCL_OK ) {
- Entity_StructSet(interp,p,offset,newValue);
- changed++;
- }
- }
- if(changed) {
- Entity_ApplySettings(p);
- }
- }
- /*
- for(i=0;i<CSTRUCT_ENTITY_Count*2;i++) {
- Tcl_DecrRefCount(varv[i]);
- }
- */
- return TCL_OK;
- }
- /* Entity_Rewind */
- void Entity_Rewind(Entity *p, int revert){}
- /* Entity_SetFromObj */
- int Entity_SetFromObj(Tcl_Interp *interp,Entity *pType, Tcl_Obj *field, Tcl_Obj *value){
- /* Manipulate the DICT representation */
- int err,type,offset=-1;
- /* Reset any cached group pointer */
- pType->gType=NULL;
- if( Entity_StructValueOffset(interp, field, &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,pType->pType,offset,value);
- if(err==TCL_OK) {
- Entity_ApplySettings(pType->pType);
- }
- return err;
- }
- Odie_HashPut(&pType->infoDict,Tcl_GetString(field),value);
- return TCL_OK;
- }
- /* Entity_SpecHashClear */
- void Entity_SpecHashClear(Entity *p){
- Odie_HashFree(&p->infoDict);
- }
- /* Entity_SpecHashPut */
- void Entity_SpecHashPut(Entity *p,Tcl_Obj *key,Tcl_Obj *value){
- Odie_HashPut(&p->infoDict,Tcl_GetString(key),value);
- }
- /* Entity_StructAddLocation */
- void Entity_StructAddLocation(Tcl_Interp *interp,Entity *p, Tcl_Obj *pValueDict){
- Tcl_Obj *tempval;
- #ifdef build_IRM
- if(p->public_class=='k') {
- /* Always provide a path if not given
- ** And only trust the local dict
- */
- Tcl_Obj *pathobj=Entity_ExportField(NULL,p->infoDict,"path",ODIE_NULL_EMPTY);
- Odie_DictObjPut(0,pValueDict,"path",pathobj);
- } else {
- if(p->attached_to) {
- switch (p->attached_type) {
- case CSTRUCT_crew: {
- return Crew_StructAddLocation(interp,p->attached_to,pValueDict);
- }
- case CSTRUCT_entity: {
- return Entity_StructAddLocation(interp,p->attached_to,pValueDict);
- }
- case CSTRUCT_portal: {
- return Portal_StructAddLocation(interp,p->attached_to,pValueDict);
- }
- case CSTRUCT_simnode: {
- return SimNode_StructAddLocation(interp,p->attached_to,pValueDict);
- }
- }
- }
- Odie_DictObjPut(0,pValueDict,"deckid",Odie_LiteralIntObj(p->deckid));
- if(p->deckid) {
- tempval=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, tempval, Odie_LiteralIntObj(p->deckid));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->x));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->y));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->zoff));
- Odie_DictObjPut(interp,pValueDict,"center",tempval);
- }
- tempval=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->nx));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->ny));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->nz));
- Odie_DictObjPut(0,pValueDict,"orientation",tempval);
- if(p->comptPtr) {
- Odie_DictObjPut(0,pValueDict,"compartment",Entity_Identify(p->comptPtr));
- }
- }
- #else
- Odie_DictObjPut(0,pValueDict,"deckid",Odie_LiteralIntObj(p->deckid));
- if(p->deckid) {
- tempval=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, tempval, Odie_LiteralIntObj(p->deckid));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->x));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->y));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->zoff));
- Odie_DictObjPut(interp,pValueDict,"center",tempval);
- }
- tempval=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->nx));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->ny));
- Tcl_ListObjAppendElement(interp, tempval, Tcl_NewIntObj(p->nz));
- Odie_DictObjPut(0,pValueDict,"orientation",tempval);
- if(p->comptPtr) {
- Odie_DictObjPut(0,pValueDict,"compartment",Entity_Identify(p->comptPtr));
- }
- #endif
- }
- /* Entity_StructAlloc */
- void Entity_StructAlloc(Entity *p){}
- /* Entity_StructAttachLocation */
- int Entity_StructAttachLocation(Tcl_Interp *interp,Entity *pNat,Tcl_Obj *nodeName){
- char type=0;
- int roid;
- char *stringVal=Tcl_GetString(nodeName);
- int result=sscanf(stringVal,"%c%d",&type,&roid);
- if(result!=2) {
- pNat->attached_type=0;
- pNat->attached_to=NULL;
- return TCL_OK;
- }
- #ifdef build_IRM
- switch(type) {
- case 'c': {
- Compartment *pDest;
- if(Compartment_FromTclObj(interp,nodeName,&pDest)) return TCL_ERROR;
- pNat->attached_type=CSTRUCT_compartment;
- pNat->attached_to=pDest;
- return TCL_OK;
- }
- case 'e': {
- SimNode *pDest;
- if(SimNode_FromTclObj(interp,nodeName,&pDest)) return TCL_ERROR;
- pNat->attached_type=CSTRUCT_simnode;
- pNat->attached_to=pDest;
- return TCL_OK;
- }
- case 'p': {
- Portal *pDest;
- if(Portal_FromTclObj(interp,nodeName,&pDest)) return TCL_ERROR;
- pNat->attached_type=CSTRUCT_portal;
- pNat->attached_to=pDest;
- return TCL_OK;
- }
- case 'v': {
- Crew *pDest;
- if(Crew_FromTclObj(interp,nodeName,&pDest)) return TCL_ERROR;
- pNat->attached_type=CSTRUCT_crew;
- pNat->attached_to=pDest;
- return TCL_OK;
- }
- default: {
- Entity *pDest;
- if(Entity_FromTclObj(interp,nodeName,&pDest)) {
- return TCL_ERROR;
- }
- pNat->attached_type=CSTRUCT_entity;
- pNat->attached_to=pDest;
- return TCL_OK;
- }
- }
- return TCL_ERROR;
- #else
- Entity *pDest;
- if(Entity_FromTclObj(interp,nodeName,&pDest)) {
- return TCL_ERROR;
- }
- pNat->attached_type=CSTRUCT_entity;
- pNat->attached_to=pDest;
- return TCL_OK;
- #endif
- }
- /* Entity_StructChanged */
- int Entity_StructChanged(Entity *p){ return 0; }
- /* Entity_StructFree */
- void Entity_StructFree(Entity *p){
- Odie_HashFree(&p->infoDict);
- p->infoDict=NULL;
- }
- /* Entity_StructFree_Private */
- void Entity_StructFree_Private(Entity *p){}
- /* Entity_StructGetGroup */
- Roid Entity_StructGetGroup(Entity *p){
- Roid groupid=-1;
- if(p->public_groupid>0) {
- return p->public_groupid;
- }
- if(p->pType) {
- groupid=SimType_StructGetGroup(p->pType);
- if(groupid>0) {
- return groupid;
- }
- }
- /*
- ** Nodes defaults to the compartment they are within
- ** If no group is given through the type or adopted type
- */
- if(p->comptPtr) {
- groupid=Entity_StructGetGroup(p->comptPtr);
- if(groupid>0) {
- return groupid;
- }
- }
- return 0;
- }
- /* Entity_StructLocation */
- void Entity_StructLocation (Irm_Location *lstruct,Entity *p){
- #ifdef build_IRM
- if(p->attached_to) {
- switch (p->attached_type) {
- case CSTRUCT_crew: {
- return Crew_StructLocation(lstruct,p->attached_to);
- }
- case CSTRUCT_entity: {
- return Entity_StructLocation(lstruct,p->attached_to);
- }
- case CSTRUCT_portal: {
- return Portal_StructLocation(lstruct,p->attached_to);
- }
- case CSTRUCT_simnode: {
- return SimNode_StructLocation(lstruct,p->attached_to);
- }
- }
- }
- #endif
- lstruct->deckid=p->deckid;
- lstruct->x=p->x;
- lstruct->y=p->y;
- lstruct->zoff=p->zoff;
- }
- /* Entity_StructMatches */
- int Entity_StructMatches(Entity *p,int *matchSearch){
- if(matchSearch[ENTITY_SEARCH_CLASS]>=0) {
- if(matchSearch[ENTITY_SEARCH_CLASS]!=(int)p->public_class) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_DECKID]>=0) {
- if(matchSearch[ENTITY_SEARCH_DECKID]!=(int)p->deckid) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_DRAWN]>=0) {
- if(matchSearch[ENTITY_SEARCH_DRAWN]!=(int)p->public_drawn) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_COMPTID]>=0) {
- Entity *gPtr=p->comptPtr;
- if(!gPtr) {
- return 0;
- } else {
- if(gPtr->id != matchSearch[ENTITY_SEARCH_COMPTID]) {
- return 0;
- }
- }
- }
- if(matchSearch[ENTITY_SEARCH_GROUPID]>=0) {
- Roid groupid=Entity_StructGetGroup(p);
- if(groupid != matchSearch[ENTITY_SEARCH_GROUPID]) {
- return 0;
- }
- }
- if(matchSearch[ENTITY_SEARCH_HIDDEN]>=0) {
- if(matchSearch[ENTITY_SEARCH_HIDDEN]!=p->public_hidden) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_ACTIVE]>=0) {
- if(matchSearch[ENTITY_SEARCH_ACTIVE]!=p->public_active) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_HIGHLIGHT]>=0) {
- if(matchSearch[ENTITY_SEARCH_HIGHLIGHT]!=p->public_highlight) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_MOVED]>=0) {
- if(matchSearch[ENTITY_SEARCH_MOVED]!=p->public_moved) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_REDRAW]>=0) {
- if(matchSearch[ENTITY_SEARCH_REDRAW]!=p->public_redraw) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_REPAINT]>=0) {
- if(matchSearch[ENTITY_SEARCH_REPAINT]!=p->public_repaint) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_SYNTHETIC]>=0) {
- if(matchSearch[ENTITY_SEARCH_SYNTHETIC]!=p->public_synthetic) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_TYPEID]>=0) {
- if(!p->pType) {
- return 0;
- } else {
- if(p->pType->id != matchSearch[ENTITY_SEARCH_TYPEID]) {
- return 0;
- }
- }
- }
- if(matchSearch[ENTITY_SEARCH_TRACE]>=0) {
- if(matchSearch[ENTITY_SEARCH_TRACE]!=p->public_trace) return 0;
- }
- if(matchSearch[ENTITY_SEARCH_VISIBLE]>=0) {
- if(matchSearch[ENTITY_SEARCH_VISIBLE]!=p->public_visible) return 0;
- }
- return 1;
- }
- /* Entity_StructSet */
- int Entity_StructSet(Tcl_Interp *interp,Entity *pNode,int field,Tcl_Obj *value){
- if(field < 0 ) {
- return TCL_ERROR;
- }
- switch (field) {
- case CSTRUCT_ENTITY_HIDDEN: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_hidden=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_IS_TYPE: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_is_type=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_REDRAW: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_redraw=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_ACTIVE: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_active=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_GROUPID: {
- Roid roidValue;
- if(Irm_GetRoidFromObj(interp,value,&roidValue)) return TCL_ERROR;
- pNode->public_groupid=(Roid)roidValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_TRACE: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_trace=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_REPAINT: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_repaint=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_VISIBLE: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_visible=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_MOVED: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_moved=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_CHANGED: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_changed=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_OPEN: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_open=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_CLASS: {
- char *str;
- str=Tcl_GetString(value);
- if(str) {
- pNode->public_class=str[0];
- }
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_PARENT: {
- Roid roidValue;
- if(Irm_GetRoidFromObj(interp,value,&roidValue)) return TCL_ERROR;
- pNode->public_parent=(Roid)roidValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_SYNTHETIC: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_synthetic=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_HIGHLIGHT: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_highlight=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_DRAWN: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_drawn=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_NCHILD: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_nchild=intValue;
- return TCL_OK;
- }
- case CSTRUCT_ENTITY_ONCOUNT: {
- int intValue;
- double floatValue;
- if(Tcl_GetIntFromObj(interp,value,&intValue)) {
- Tcl_ResetResult(interp);
- if(Tcl_GetDoubleFromObj(interp,value,&floatValue)) return TCL_ERROR;
- intValue=(int)floatValue;
- }
- pNode->public_oncount=intValue;
- return TCL_OK;
- }
- }
- return TCL_OK;
- }
- /* Entity_StructSetGroup */
- void Entity_StructSetGroup(Entity *p,Roid groupid){
- p->public_groupid=groupid;
- }
- /* Entity_StructSetType */
- void Entity_StructSetType(Entity *p,Entity *pType){
- p->pType=pType;
- if(pType) {
- if(pType->public_class=='g') {
- p->gType=pType;
- }
- }
- }
- /* Entity_StructSizeZ */
- int Entity_StructSizeZ(Entity *pNode){
- int zheight=TypeSpec_GetInt(pNode,"size.z");
- return zheight;
- }
- /* Entity_StructValueOffset */
- int Entity_StructValueOffset(Tcl_Interp *interp,Tcl_Obj *pObj,int *pIndex,int *pType){
- /*
- ** Given the name of one of the arState[] values in the Entity structure,
- ** return the index of the particular arState[]. Return TCL_OK.
- **
- ** Leave an error message in interp and return TCL_ERROR if
- ** anything goes wrong.
- */
- int lo, hi, mid, c, max, i;
- int nName;
- const char *zName;
- const struct OdieParamNameMap *aParam = Entity_canonicalNameMap;
- lo = 0;
- hi = max = CSTRUCT_ENTITY_AliasCount - 1;
- zName = Tcl_GetStringFromObj(pObj, &nName);
- mid = (lo+hi)/2;
- if(nName>32) {
- nName=32;
- }
- while( lo<=hi ){
- mid = (lo+hi)/2;
- c = strncmp(zName, aParam[mid].zName, nName);
- if( c<0 ){
- hi = mid-1;
- }else if( c>0 ){
- lo = mid+1;
- }else if(
- (mid>0 && strncmp(zName, aParam[mid-1].zName, nName)==0) ||
- (mid<max && strncmp(zName, aParam[mid+1].zName, nName)==0)
- ){
- i = mid;
- while( i>0 && strncmp(zName, aParam[i-1].zName, nName)==0 ){
- i--;
- }
- if( strlen(aParam[i].zName)==nName ){
- *pIndex = aParam[i].iCode;
- *pType = aParam[i].pType;
- return TCL_OK;
- }
- if(interp) {
- Tcl_AppendResult(interp, "ambiguous parameter:", 0);
- do{
- Tcl_AppendResult(interp, " ", aParam[i++].zName, 0);
- }while( i<=max && strncmp(zName, aParam[i].zName, nName)==0 );
- }
- return TCL_ERROR;
- }else{
- *pIndex = aParam[mid].iCode;
- *pType = aParam[mid].pType;
- return TCL_OK;
- }
- }
- if(interp) {
- Tcl_AppendResult(interp, "unknown parameter \"", zName,
- "\" - nearby choices:", 0);
- for(i=mid-3; i<mid+3; i++){
- if( i<0 || i>max ) continue;
- Tcl_AppendResult(interp, " ", aParam[i].zName, 0);
- }
- }
- return TCL_ERROR;
- }
- /* Entity_StructWith */
- void Entity_StructWith(Tcl_Interp *interp,Entity *p,int virtual,Tcl_Obj **objvPtr){
- int i;
- if (virtual) {
- Entity_With(interp,p->pType,NULL);
- }
- /* Finaly, Add the Tcl Data */
- for(i=0;i<CSTRUCT_ENTITY_Count;i++) {
- Tcl_Obj *newElement=Entity_StructGet(p,i);
- Tcl_Obj *fieldName=Odie_LiteralStringObj(Entity_paramNameMap[i].zName);
- if(objvPtr) {
- objvPtr[i*2]=fieldName;
- objvPtr[i*2+1]=newElement;
- }
- Tcl_ObjSetVar2(interp,fieldName,NULL,newElement,0);
- }
- if(virtual) {
- Entity_StructWithLocation(interp,p);
- }
- }
- /* Entity_StructWithLocation */
- void Entity_StructWithLocation(Tcl_Interp *interp,Entity *pNode){}
- /* Entity_Unlink */
- void Entity_Unlink(Entity *objPtr){
- Tcl_HashEntry *pEntry;
- if (!objPtr) return;
- if(CurrentSim->GlobalSim) {
- pEntry=Tcl_FindHashEntry(&CurrentSim->GlobalSim->EntityIdSet,(const char *)objPtr->name);
- } else {
- pEntry=Tcl_FindHashEntry(&CurrentSim->EntityIdSet,(const char *)objPtr->name);
- }
- if(pEntry) {
- Tcl_DeleteHashEntry(pEntry);
- }
- #ifdef build_IRM
- if(objPtr->public_class=='v') {
- Crew *pNode=Crew_ById(objPtr->id,0);
- if(pNode) {
- Crew_Unlink(pNode);
- Crew_Delete(pNode);
- }
- }
- if(objPtr->public_class=='p') {
- Portal *pNode=Portal_ById(objPtr->id,0);
- if(pNode) {
- Portal_Unlink(pNode);
- Portal_Delete(pNode);
- }
- }
- if(objPtr->public_class=='k') {
- SimLink *pNode=SimLink_ById(objPtr->id,0);
- if(pNode) {
- SimLink_Unlink(pNode);
- SimLink_Delete(pNode);
- }
- }
- if(objPtr->public_class=='e') {
- SimNode *pNode=SimNode_ById(objPtr->id,0);
- if(pNode) {
- if(pNode->aLink->pCommon->public_rupture_node == pNode->id) {
- /*
- ** Run link repair for rupture nodes instead of delete simnode
- */
- SimLink_Repair(NULL,pNode->aLink->pCommon);
- } else {
- SimNode_Unlink(pNode);
- SimNode_Delete(pNode);
- }
- }
- }
- #endif
- }
- /* Entity_With */
- void Entity_With(Tcl_Interp *interp,Entity *e,Tcl_HashTable *local){
- Tcl_HashTable *localDict=NULL;
- Entity *p=NULL;
- Entity *pStack[10];
- int i,count=-1;
- p=e;
- while(p && count<10) {
- count++;
- pStack[count]=p;
- p=p->pType;
- }
- /*
- ** Add the minimum specs for the class
- */
- for(i=count;i>=0;i--) {
- p=pStack[i];
- localDict=p->infoDict;
- if(localDict) {
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- for(i=Tcl_FirstHashEntry(localDict,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Tcl_Obj *pKey,*pValue;
- pKey=Odie_LiteralStringObj(Tcl_GetHashKey(localDict,i));
- pValue=(Tcl_Obj *)Tcl_GetHashValue(i);
- Tcl_ObjSetVar2(interp,pKey,NULL,pValue,0);
- }
- }
- }
- localDict=local;
- if(localDict) {
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- for(i=Tcl_FirstHashEntry(localDict,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Tcl_Obj *pKey,*pValue;
- pKey=Odie_LiteralStringObj(Tcl_GetHashKey(localDict,i));
- pValue=(Tcl_Obj *)Tcl_GetHashValue(i);
- Tcl_ObjSetVar2(interp,pKey,NULL,pValue,0);
- }
- }
- }
- #define ENTITY_SEARCH_NCOUNT 15
- /* *SimType_ById */
- Entity *SimType_ById(Roid id, int createFlag){
- /*
- ** Return a pointer to a SimType with the given ID. Return NULL
- ** if there is no such type. Create a new one if the createFlag
- ** is true and the type does not previously exist.
- */
- Tcl_HashEntry *pEntry;
- if(CurrentSim->GlobalSim) {
- pEntry=Tcl_FindHashEntry(&CurrentSim->GlobalSim->SimTypeIdSet,(char *)id);
- } else {
- pEntry=Tcl_FindHashEntry(&CurrentSim->SimTypeIdSet,(char *)id);
- }
- if(pEntry) {
- return (Entity*)Tcl_GetHashValue(pEntry);
- }
- if(createFlag) {
- int isNew;
- Entity *p;
- if(CurrentSim->GlobalSim) {
- pEntry = Tcl_CreateHashEntry(&CurrentSim->GlobalSim->SimTypeIdSet,(char *)id, &isNew);
- } else {
- pEntry = Tcl_CreateHashEntry(&CurrentSim->SimTypeIdSet,(char *)id, &isNew);
- }
- p = (Entity *)Odie_Alloc( sizeof(*p) );
- p->id = id;
- p->pType=NULL;
- Entity_StructAlloc(p);
- p->public_is_type=1;
- Tcl_SetHashValue(pEntry,(ClientData)p);
- return p;
- }
- return NULL;
- }
- /* *SimType_ByName */
- Entity *SimType_ByName(char *idstring, int createFlag){
- Roid i=-1;
- i=Odie_RoidFromString(idstring,'y');
- if(i<0) {
- return NULL;
- }
- return SimType_ById(i,createFlag);
- }
- /* *SimType_First */
- Tcl_HashEntry *SimType_First(Simulator *sim,Tcl_HashSearch *search){
- /*
- ** Return the first entity in a list of them all
- */
- if(sim->GlobalSim) {
- return Tcl_FirstHashEntry(&sim->GlobalSim->SimTypeIdSet,search);
- } else {
- return Tcl_FirstHashEntry(&sim->SimTypeIdSet,search);
- }
- }
- /* *SimType_GroupToTclObj */
- Tcl_Obj *SimType_GroupToTclObj(Entity *pNode){
- Roid groupid;
- if(!pNode) {
- return Tcl_NewBooleanObj(0);
- }
- groupid=SimType_StructGetGroup(pNode);
- if(!groupid) {
- return Tcl_NewBooleanObj(0);
- }
- return Irm_NewRoidObj(groupid);
- }
- /* *SimType_Identify */
- Tcl_Obj *SimType_Identify(Entity *pNode){
- if(!pNode) {
- return Irm_NewRoidObj(0);
- }
- return Irm_NewRoidObj(pNode->id);
- }
- /* *SimType_PublicId */
- Tcl_Obj *SimType_PublicId(Entity *pNode){
- char idstring[64];
- if(!pNode) {
- return Irm_NewRoidObj(0);
- }
- if(pNode->pType) {
- if(pNode->pType->name!=NULL) {
- return Odie_LiteralStringObj(pNode->pType->name);
- }
- }
- sprintf(idstring,"y%d",pNode->id);
- return Odie_LiteralStringObj(idstring);
- }
- /* *SimType_StructGetType */
- Entity *SimType_StructGetType(Entity *p){
- if(p->pType) {
- return Entity_StructGetType(p->pType);
- }
- return NULL;
- }
- /* *SimType_StructToDict */
- Tcl_Obj *SimType_StructToDict(Tcl_Interp *interp,Entity *p,int virtual){
- Tcl_Obj *pResult=NULL;
- if (virtual) {
- pResult=Entity_GetDict(p->pType,NULL);
- }
- return pResult;
- }
- /* *SimType_TypeToTclObj */
- Tcl_Obj *SimType_TypeToTclObj(Entity *pNode){
- Entity *pType;
- if(!pNode) {
- return Tcl_NewBooleanObj(0);
- }
- pType=SimType_StructGetType(pNode);
- if(!pType) {
- return Tcl_NewBooleanObj(0);
- }
- return Irm_NewRoidObj(pType->id);
- }
- /* SimType_ApplySettings */
- inline extern void SimType_ApplySettings(Entity *p){
- /* Default implementation does nothing */
- }
- /* SimType_FromTclObj */
- int SimType_FromTclObj(Tcl_Interp *interp, Tcl_Obj *pObj, Entity **ppEntity){
- /*
- ** Find a SimType given a Tcl_Obj that contains the SimType ID.
- ** Leave an error message in interp and return TCL_ERROR if anything
- ** goes wrong.
- */
- Roid i=-1;
- i=Odie_RoidFromString(Tcl_GetString(pObj),'y');
- if(i<0) {
- if(interp) {
- Tcl_AppendResult(interp, "no such SimType: ",
- Tcl_GetStringFromObj(pObj, 0), 0);
- }
- }
- *ppEntity = SimType_ById(i, 0);
- if( *ppEntity==0 ){
- if(interp) {
- Tcl_AppendResult(interp, "no such SimType: ",
- Tcl_GetStringFromObj(pObj, 0), 0);
- }
- return TCL_ERROR;
- }
- return TCL_OK;
- }
- /* SimType_Module_Advance */
- void SimType_Module_Advance(Simulator *ActiveSim,int clocktime){}
- /* SimType_nodeeval */
- int SimType_nodeeval(Tcl_Interp *interp,Entity *p,Tcl_Obj *body,int writeback){
- Tcl_Obj *id;
- int i,len;
- Tcl_Obj *varv[CSTRUCT_ENTITY_Count*2];
- int result;
- Entity_StructWith(interp,p,1,varv);
- id=SimType_Identify(p);
- Tcl_ObjSetVar2(interp,Odie_LiteralStringObj("id"),NULL,id,0);
- Tcl_ObjSetVar2(interp,Odie_LiteralStringObj("typeid"),NULL,SimType_TypeToTclObj(p),0);
- Tcl_ObjSetVar2(interp,Odie_LiteralStringObj("groupid"),NULL,SimType_GroupToTclObj(p),0);
- /*
- for(i=0;i<CSTRUCT_ENTITY_Count*2;i++) {
- Tcl_IncrRefCount(varv[i]);
- }
- */
- result=Tcl_EvalObjEx(interp, body, 0);
- if(result!=TCL_OK) {
- return result;
- }
- if(writeback){
- /*
- ** Read values back into the dict
- ** For now, we limit writeback to state variables
- ** And we don't care about garbage values
- */
- int changed=0;
- for(i=0;i<CSTRUCT_ENTITY_Count*2;i+=2) {
- Tcl_Obj *newValue;
- int offset;
- int type;
- newValue=Tcl_ObjGetVar2(interp,varv[i],(Tcl_Obj*)NULL,0);
- if(newValue==varv[i+1]) {
- /* Undocumented, unsanctioned, but it works in practice
- ** If the pointer hasn't changed, neither has the value
- */
- continue;
- }
- if(!newValue) {
- /* Variable must have been unset... move along */
- continue;
- }
- if( Entity_StructValueOffset(0, varv[i], &offset, &type) == TCL_OK ) {
- Entity_StructSet(interp,p,offset,newValue);
- changed++;
- }
- }
- if(changed) {
- Entity_ApplySettings(p);
- }
- }
- /*
- for(i=0;i<CSTRUCT_ENTITY_Count*2;i++) {
- Tcl_DecrRefCount(varv[i]);
- }
- */
- return TCL_OK;
- }
- /* SimType_Rewind */
- void SimType_Rewind(Entity *p, int revert){}
- /* SimType_StructGetGroup */
- Roid SimType_StructGetGroup(Entity *p){
- if(!p) {
- return 0;
- }
- if (p->public_class=='g') {
- return p->id;
- }
- if(p->public_groupid) {
- return p->public_groupid;
- }
- if(p->public_parent) {
- Entity *pType=SimType_ById(p->public_parent,0);
- if(pType) {
- if (pType->public_class=='g') {
- return pType->id;
- }
- /* Otherwise, keep looking for parents */
- return SimType_StructGetGroup(pType);
- }
- }
- return 0;
- }
- /* SimType_StructSetGroup */
- void SimType_StructSetGroup(Entity *p,Roid groupid){
- p->public_groupid=groupid;
- }
- /* SimType_StructSetType */
- void SimType_StructSetType(Entity *p,Entity *pType){
- if(!p->pType) {
- return;
- }
- Entity_StructSetType(p->pType,pType);
- }
- /* SimType_StructWith */
- void SimType_StructWith(Tcl_Interp *interp,Entity *p,int virtual){
- if (virtual) {
- Entity_With(interp,p->pType,p->infoDict);
- }
- }
- /* SimType_Unlink */
- void SimType_Unlink(Entity *objPtr){
- Tcl_HashEntry *pEntry;
- if(CurrentSim->GlobalSim) {
- pEntry=Tcl_FindHashEntry(&CurrentSim->GlobalSim->SimTypeIdSet,(char *)objPtr->id);
- } else {
- pEntry=Tcl_FindHashEntry(&CurrentSim->SimTypeIdSet,(char *)objPtr->id);
- }
- if(pEntry) {
- Tcl_DeleteHashEntry(pEntry);
- }
- }
- /* TypeSpec_SetInt */
- void TypeSpec_SetInt(Entity *pType,char *field, int value){
- Tcl_Obj *newValue;
- if(!pType) return;
- newValue=Tcl_NewIntObj(value);
- Odie_HashPut(&pType->infoDict,field,newValue);
- //Tcl_DecrRefCount(newValue);
- }
- /* TypeSpec_SetReal */
- void TypeSpec_SetReal(Entity *pType,char *field, IrmReal value){
- Tcl_Obj *newValue;
- if(!pType) return;
- double fabsvalue=fabs(value);
- if(fabsvalue == value && fabsvalue < 10 ) {
- TypeSpec_SetInt(pType,field,(int)value);
- return;
- }
- newValue=Tcl_NewDoubleObj((double)value);
- Odie_HashPut(&pType->infoDict,field,newValue);
- //Tcl_DecrRefCount(newValue);
- }
- /* TypeSpec_SetWideInt */
- void TypeSpec_SetWideInt(Entity *pType, char *field, Tcl_WideInt value){
- Tcl_Obj *newValue;
- if(!pType) return;
- if(value > -10 && value < 10) {
- TypeSpec_SetInt(pType,field,(int)value);
- return;
- }
- newValue=Tcl_NewWideIntObj(value);
- Odie_HashPut(&pType->infoDict,field,newValue);
- //Tcl_DecrRefCount(newValue);
- }
- /* TypeSpec_Exists */
- IrmReal TypeSpec_Exists(Entity *pType, char *field){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- return 1;
- }
- return 0;
- }
- /* TypeSpec_GetReal */
- IrmReal TypeSpec_GetReal(Entity *pType, char *field){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- double s;
- if (Tcl_GetDoubleFromObj(NULL,result,&s)==TCL_OK) {
- return s;
- }
- }
- return 0.0;
- }
- /* TypeSpec_GetReal_Or_Default */
- IrmReal TypeSpec_GetReal_Or_Default(Entity *pType, char *field,IrmReal defaultValue){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- double s;
- if (Tcl_GetDoubleFromObj(NULL,result,&s)==TCL_OK) {
- return s;
- }
- }
- return defaultValue;
- }
- /* TypeSpec_GetInt */
- int TypeSpec_GetInt(Entity *pType, char *field){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- int sint;
- double s;
- if (Tcl_GetIntFromObj(NULL,result,&sint)==TCL_OK) {
- return sint;
- }
- if (Tcl_GetDoubleFromObj(NULL,result,&s)==TCL_OK) {
- return (int)round(s);
- }
- }
- return 0;
- }
- /* TypeSpec_GetInt_or_Default */
- int TypeSpec_GetInt_or_Default(Entity *pType, char *field,int dValue){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- int sint;
- double s;
- if (Tcl_GetIntFromObj(NULL,result,&sint)==TCL_OK) {
- return sint;
- }
- if (Tcl_GetDoubleFromObj(NULL,result,&s)==TCL_OK) {
- return (int)round(s);
- }
- }
- return dValue;
- }
- /* TypeSpec_WideInt */
- Tcl_WideInt TypeSpec_WideInt(Entity *pType, char *field){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- Tcl_WideInt c;
- if(Tcl_GetWideIntFromObj(NULL,result,&c)==TCL_OK) {
- return c;
- }
- }
- return 0;
- }
- /* *TypeSpec_GetTclObj */
- Tcl_Obj *TypeSpec_GetTclObj(Entity *pType, char *field){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- if(result) {
- return result;
- }
- return Tcl_NewObj();
- }
- /* *TypeSpec_GetTclObj_OR_NULL */
- Tcl_Obj *TypeSpec_GetTclObj_OR_NULL(Entity *pType, char *field){
- Tcl_Obj *result=NULL;
- if(field && pType) {
- result=Entity_GetField(pType->pType,pType->infoDict,field);
- }
- return result;
- }
- /* *TypeSpec_GetLogicSet */
- Tcl_Obj *TypeSpec_GetLogicSet(Entity *pType, char *field){
- if(field && pType) {
- return Entity_GetField(pType->pType,pType->infoDict,field);
- }
- return NULL;
- }
- /* END generate-cfile-functions */
- /* BEGIN generate-cfile-tclapi */
- /* Tcl Proc ::odiemath::distance */
- static int TclCmd_odiemath_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- double result;
- if( objc<1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "i1 i2 ?j1 j2? ?k1 k2?");
- return TCL_ERROR;
- }
- result=0.0;
- for(i=1;i<objc;i+=2) {
- double a,b,dx;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&a)) return TCL_ERROR;
- if(i+1>=objc) {
- Tcl_AppendResult(interp, "Odd number of arguments",(char*)0);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&b)) return TCL_ERROR;
- dx=b-a;
- result=result+dx*dx;
- }
- result=sqrt(result);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::dist3d */
- static int TclCmd_odiemath_dist3d(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double result,ax,ay,az,bx,by,bz,dx,dy,dz;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x0 y0 z0 x1 y1 z1");
- return TCL_ERROR;
- }
- result=0.0;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&ax)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ay)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&az)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&bx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&by)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[6],&bz)) return TCL_ERROR;
- dx=bx-ax;
- dy=by-ay;
- dz=bz-az;
- result=sqrt(dx*dx + dy*dy + dz*dz);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::grid_hex */
- static int TclCmd_odiemath_grid_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double grid, x, y;
- int gx,gy;
- Tcl_Obj *pResult;
- if( objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize x y");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&y)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- gy=(int)round(y/grid);
- if(gy%2==1){
- gx=(int)round((x-grid/2)/grid);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*gx+grid/2));
- } else {
- gx=(int)round(x/grid);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*gx));
- }
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*gy));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::grid_round */
- static int TclCmd_odiemath_grid_round(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x,q;
- int i;
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- for(i=1;i<objc;i++) {
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- q=OdieGrain*round(x/OdieGrain);
- if(x-q>(OdieGrain*0.5)) {
- q+=OdieGrain;
- }
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(q));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::grid_square */
- static int TclCmd_odiemath_grid_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double grid;
- double x;
- double y;
- Tcl_Obj *pResult;
- if( objc < 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize x y...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&y)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*round(x/grid)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*round(y/grid)));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::list_round */
- static int TclCmd_odiemath_list_round(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i, n;
- double factor;
- Tcl_Obj *pResult;
- if( objc < 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize list\ngridsize element ?element?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&factor)) return TCL_ERROR;
- if(objc==3) {
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=0;i<n;i++) {
- double thisval,remainder;
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if(Tcl_GetDoubleFromObj(interp,pObj,&thisval)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- remainder=fmod(thisval,factor);
- Tcl_ListObjAppendElement(interp, pResult, ODIE_NewFuzzyObj(thisval-remainder));
- }
- } else {
- pResult=Tcl_NewObj();
- for(i=2;i<objc;i++) {
- double thisval,remainder;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&thisval)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- remainder=fmod(thisval,factor);
- Tcl_ListObjAppendElement(interp, pResult, ODIE_NewFuzzyObj(thisval-remainder));
- }
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::list_to_int */
- static int TclCmd_odiemath_list_to_int(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- for(i=1;i<objc;i++) {
- double thisval;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&thisval)) return TCL_ERROR;
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj((int)thisval));
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::matrix_rotate_angle */
- static int TclCmd_odiemath_matrix_rotate_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- double angle;
- if( (objc != 2) && (objc != 3) ){
- Tcl_WrongNumArgs(interp, 1, objv, "angle ?units?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&angle)) return TCL_ERROR;
- if(objc==3) {
- /* Scale by the unit */
- char *units;
- units=Tcl_GetString(objv[2]);
- if(units[0]=='d') {
- angle=angle/180.0*M_PI;
- } else if (units[0]=='g') {
- angle=angle/200.0*M_PI;
- } else if (units[0]=='r') {
- } else {
- Tcl_AppendResult(interp, "Unknown unit ", units, " use d[egrees], r[adians], or g[radients]. Radians are assumed",(char*)0);
- return TCL_ERROR;
- }
- }
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(-sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(0.0));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(0.0));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::matrix_rotate_normal */
- static int TclCmd_odiemath_matrix_rotate_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- double nx,ny,angle;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "nx ny");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&nx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ny)) return TCL_ERROR;
- angle=atan2(ny,nx);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(-sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(0.0));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(0.0));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::normal */
- static int TclCmd_odiemath_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x0,y0,x1,y1;
- double L,dx,dy;
- Tcl_Obj *pResult;
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x0 y0 x1 y1");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&x0)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&y0)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&x1)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&y1)) return TCL_ERROR;
- dx=x1-x0;
- dy=y1-y0;
- L=sqrt(dx*dx+dy*dy);
- pResult=Tcl_NewObj();
- if(ODIE_Real_Is_Zero(L)) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(100));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(0));
- } else {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj((int)100*(dx/L)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj((int)100*(dy/L)));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::perpendicular */
- static int TclCmd_odiemath_perpendicular(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x0,y0,x1,y1;
- double L,dx,dy;
- Tcl_Obj *pResult;
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x0 y0 x1 y1");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&x0)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&y0)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&x1)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&y1)) return TCL_ERROR;
- dx=y1-y0;
- dy=x0-x1;
- L=sqrt(dx*dx+dy*dy);
- pResult=Tcl_NewObj();
- if(ODIE_Real_Is_Zero(L)) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(100));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(0));
- } else {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj((int)100*(dx/L)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj((int)100*(dy/L)));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::normal_2d */
- static int TclCmd_odiemath_normal_2d(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double nx,ny,norm;
- int ox,oy;
- Tcl_Obj *pResult;
- if( objc < 3 ){
- ox=100;
- oy=0;
- } else {
- if(Tcl_GetDoubleFromObj(interp,objv[1],&nx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ny)) return TCL_ERROR;
- norm=sqrt(nx*nx+ny*ny);
- if(norm<=0.0) {
- ox=100.0;
- oy=0.0;
- } else {
- ox=100*nx/norm;
- oy=100*ny/norm;
- }
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(ox));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(oy));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::parallel_segment */
- static int TclCmd_odiemath_parallel_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x0,y0,x1,y1,offset;
- double L,dx,dy;
- Tcl_Obj *pResult;
- if( objc != 6 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x0 y0 x1 y1 offset");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&x0)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&y0)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&x1)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&y1)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&offset)) return TCL_ERROR;
- dx=x0-x1;
- dy=y0-y1;
- L=sqrt(dx*dx+dy*dy);
- if(ODIE_Real_Is_Zero(dx)) {
- offset*=-1.0;
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(x0+offset*dy/L));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(y0+offset*dx/L));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(x1+offset*dy/L));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(y1+offset*dx/L));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::vector_length */
- static int TclCmd_odiemath_vector_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- double result,sum=0.0;
- if( objc<1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x ?y? ?z? ?...?");
- return TCL_ERROR;
- }
- result=0.0;
- for(i=1;i<objc;i++) {
- double a;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&a)) return TCL_ERROR;
- sum+=a*a;
- }
- result=sqrt(sum);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::vector_rotate_and_size */
- static int TclCmd_odiemath_vector_rotate_and_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double nx,ny,scalex,scaley,angle;
- if( objc < 7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "normalx normaly sizex sizey x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&nx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ny)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&scalex)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&scaley)) return TCL_ERROR;
- angle=atan2(ny,nx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- scalex*=0.5;
- scaley*=0.5;
- for(i=5;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=x*scalex;
- sy=y*scaley;
- newx=matA[0]*sx+matA[1]*sy+matA[4];
- newy=matA[2]*sx+matA[3]*sy+matA[5];
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::vector_scale */
- static int TclCmd_odiemath_vector_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double scalex,scaley;
- if( objc < 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "sizex sizey x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&scalex)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&scaley)) return TCL_ERROR;
- scalex*=0.5;
- scaley*=0.5;
- for(i=3;i<objc;i+=2) {
- double x,y,sx,sy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=x*scalex;
- sy=y*scaley;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::vector_translate_and_zoom */
- static int TclCmd_odiemath_vector_translate_and_zoom(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double zoom;
- double centerx,centery;
- if( objc < 6 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- for(i=4;i<objc;i+=2) {
- double x,y,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- newx=(x/zoom)+centerx;
- newy=(y/zoom)+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::grid */
- static int TclCmd_odiemath_grid(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if( objc > 1 ){
- if(Tcl_GetDoubleFromObj(interp,objv[1],&OdieGrain)) return TCL_ERROR;
- }
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(OdieGrain));
- return TCL_OK;
- }
- /* Tcl Proc ::odiemath::tolerance */
- static int TclCmd_odiemath_tolerance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if( objc > 1 ){
- if(Tcl_GetDoubleFromObj(interp,objv[1],&OdieTolerance)) return TCL_ERROR;
- }
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(OdieTolerance));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::create */
- static int TclCmd_odie_aabb_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *C;
- C=Odie_MatrixObj_Create(MATFORM_aabb_xyz);
- VectorXYZ_AABB_Reset(C->matrix);
- if(objc==7) {
- int i;
- for(i=1;i<objc;i++) {
- if(Tcl_GetDoubleFromObj(interp,objv[1],&C->matrix[i-1])) return TCL_ERROR;
- }
- } else if(objc>1) {
- int i;
- VectorXYZ point;
- for(i=1;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],point)) return TCL_ERROR;
- VectorXYZ_AABB_Measure(point,C->matrix);
- }
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::overlap_two_vectors */
- static int TclCmd_odie_aabb_overlap_two_vectors(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ a1,a2,b1,b2;
- double c;
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A1 A2 B1 B2");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],a1)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],a2)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],b1)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[4],b2)) return TCL_ERROR;
- c=VectorXYZ_BBOX_Overlap_TwoVectors(a1,a2,b1,b2);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::measure */
- static int TclCmd_odie_aabb_measure(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *C;
- Tcl_Obj *varname,*pResult;
- int i;
- VectorXYZ point;
- if( objc < 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BBOX VECTORXYZ ?VECTORXYZ..?");
- return TCL_ERROR;
- }
- varname=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(Odie_GetMatrixFromTclObj(interp,varname,MATFORM_aabb_xyz,&C)) return TCL_ERROR;
- VectorXYZ_AABB_Normalize(C->matrix);
- for(i=2;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],point)) return TCL_ERROR;
- VectorXYZ_AABB_Measure(point,C->matrix);
- }
- Tcl_InvalidateStringRep(varname);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::faces */
- static int TclCmd_odie_aabb_faces(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double VALUES[6];
- double scale=1.0;
- Tcl_Obj *pResult,*pRow;
- if( objc != 2 && objc != 3 && objc != 7 && objc != 8){
- Tcl_WrongNumArgs(interp, 1, objv, "AABB ?SCALE?\nx0 y0 z0 x1 y1 z1 ?SCALE?");
- return TCL_ERROR;
- }
- if(objc==2 || objc==3) {
- MATOBJ *A;
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_aabb_xyz,&A)) return TCL_ERROR;
- if(objc==3) {
- if(Tcl_GetDoubleFromObj(interp,objv[2],&scale)) {
- scale=1.0;
- }
- }
- VALUES[X_MIN_IDX]=A->matrix[X_MIN_IDX];
- VALUES[Y_MIN_IDX]=A->matrix[Y_MIN_IDX];
- VALUES[Z_MIN_IDX]=A->matrix[Z_MIN_IDX];
- VALUES[X_MAX_IDX]=A->matrix[X_MAX_IDX];
- VALUES[Y_MAX_IDX]=A->matrix[Y_MAX_IDX];
- VALUES[Z_MAX_IDX]=A->matrix[Z_MAX_IDX];
- } else {
- if(objc==8) {
- if(Tcl_GetDoubleFromObj(interp,objv[7],&scale)) {
- scale=1.0;
- }
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&VALUES[0])!=TCL_OK) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&VALUES[1])!=TCL_OK) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&VALUES[2])!=TCL_OK) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&VALUES[3])!=TCL_OK) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&VALUES[4])!=TCL_OK) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[6],&VALUES[5])!=TCL_OK) return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- pRow=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pResult,pRow);
- pRow=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pResult,pRow);
- pRow=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pResult,pRow);
- pRow=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pResult,pRow);
- pRow=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pResult,pRow);
- pRow=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[X_MAX_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Y_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pRow,Tcl_NewDoubleObj(VALUES[Z_MIN_IDX]*scale));
- Tcl_ListObjAppendElement(interp,pResult,pRow);
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::from_vectorxyz */
- static int TclCmd_odie_aabb_from_vectorxyz(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*C;
- if( objc < 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BBOX\nor\nA B ?C...?");
- return TCL_ERROR;
- }
- if(objc==2) {
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_aabb_xyz,&C)) return TCL_ERROR;
- VectorXYZ_AABB_Normalize(C->matrix);
- } else {
- int i;
- C=Odie_MatrixObj_Create(MATFORM_aabb_xyz);
- VectorXYZ_AABB_Reset(C->matrix);
- for(i=1;i<objc;i++) {
- if(Odie_GetMatrixFromTclObj(interp,objv[i],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- VectorXYZ_AABB_Measure(A->matrix,C->matrix);
- }
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::from_line */
- static int TclCmd_odie_aabb_from_line(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B;
- VectorXYZ AA,BB;
- Tcl_Obj *pResult=Tcl_NewObj();
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- AA[X_IDX]=min(A[X_IDX],B[X_IDX]);
- AA[Y_IDX]=min(A[Y_IDX],B[Y_IDX]);
- AA[Z_IDX]=min(A[Z_IDX],B[Z_IDX]);
- BB[X_IDX]=max(A[X_IDX],B[X_IDX]);
- BB[Y_IDX]=max(A[Y_IDX],B[Y_IDX]);
- BB[Z_IDX]=max(A[Z_IDX],B[Z_IDX]);
- pResult=Tcl_NewObj();;
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(AA));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(BB));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::from_center_size */
- static int TclCmd_odie_aabb_from_center_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ center,size;
- VectorXYZ AA,BB;
- Tcl_Obj *pResult=Tcl_NewObj();
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "center size");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],center)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],size)) return TCL_ERROR;
- size[X_IDX]*=0.5;
- size[Y_IDX]*=0.5;
- size[Z_IDX]*=0.5;
- pResult=Tcl_NewObj();
- VectorXYZ_Subtract(AA,center,size);
- VectorXYZ_Add(BB,center,size);
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(AA));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(BB));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::intersect */
- static int TclCmd_odie_aabb_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*B;
- int c;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "AABB AABB");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_aabb_xyz,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_aabb_xyz,&B)) return TCL_ERROR;
- c=AABB_AABB_Intersect(A->matrix,B->matrix);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::aabb::within */
- static int TclCmd_odie_aabb_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*B;
- double c;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "AABB POINT");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_aabb_xyz,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_vectorxyz,&B)) return TCL_ERROR;
- c=VectorXYZ_AABB_Within(B->matrix,A->matrix);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::affine2d::apply */
- static int TclCmd_affine2d_apply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double matA[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
- if( objc < 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "matrix x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- for(i=0;i<6;i++) {
- Tcl_Obj *temp;
- if(Tcl_ListObjIndex(interp, objv[1], i, &temp)) return TCL_ERROR;
- if(Odie_GetMatrixElementFromObj(interp,temp,matA,i)) return TCL_ERROR;
- }
- for(i=2;i<objc;i+=2) {
- double x,y,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- newx=matA[0]*x+matA[1]*y+matA[4];
- newy=matA[2]*x+matA[3]*y+matA[5];
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::affine2d::combine */
- static int TclCmd_affine2d_combine(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,idx;
- Tcl_Obj *pResult=Tcl_NewObj();
- double matA[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
- double matB[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
- if( objc < 2){
- Tcl_WrongNumArgs(interp, 1, objv, "transformA transformB ?transformC?...");
- return TCL_ERROR;
- }
- for(i=0;i<6;i++) {
- Tcl_Obj *temp;
- if(Tcl_ListObjIndex(interp, objv[1], i, &temp)) return TCL_ERROR;
- if(Odie_GetMatrixElementFromObj(interp,temp,matA,i)) return TCL_ERROR;
- }
- for(idx=2;idx<objc;idx++) {
- for(i=0;i<6;i++) {
- Tcl_Obj *temp;
- if(Tcl_ListObjIndex(interp, objv[idx], i, &temp)) return TCL_ERROR;
- if(Odie_GetMatrixElementFromObj(interp,temp,matB,i)) return TCL_ERROR;
- }
- matA[0]=matA[0]*matB[0]+matA[2]*matB[2]; /* [expr {$a*$i+$c*$j}] */
- matA[1]=matA[1]*matB[0]+matA[3]*matB[2]; /* [expr {$b*$i+$d*$j}] */
- matA[2]=matA[0]*matB[2]+matA[2]*matB[3]; /* [expr {$a*$k+$c*$l}] */
- matA[3]=matA[1]*matB[2]+matA[3]*matB[3]; /* [expr {$b*$k+$d*$l}] */
- matA[4]=matA[4]*matB[0]+matA[5]*matB[1]+matB[4]; /* [expr {$e*$i+$f*$j+$m}] */
- matA[5]=matA[4]*matB[2]+matA[5]*matB[3]+matB[5]; /* [expr {$e*$k+$f*$l+$n}]] */
- }
- for(i=0;i<6;i++) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(matA[i]));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::affine2d::rotation_from_angle */
- static int TclCmd_affine2d_rotation_from_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- double angle;
- if( (objc != 2) && (objc != 3) ){
- Tcl_WrongNumArgs(interp, 1, objv, "angle ?units?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&angle)) return TCL_ERROR;
- if(objc==3) {
- /* Scale by the unit */
- char *units;
- units=Tcl_GetString(objv[2]);
- if(units[0]=='d') {
- angle=angle/180.0*M_PI;
- } else if (units[0]=='g') {
- angle=angle/200.0*M_PI;
- } else if (units[0]=='r') {
- } else {
- Tcl_AppendResult(interp, "Unknown unit ", units, " use d[egrees], r[adians], or g[radients]. Radians are assumed",(char*)0);
- return TCL_ERROR;
- }
- }
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(-sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,ODIE_REAL_ZERO());
- Tcl_ListObjAppendElement(interp,pResult,ODIE_REAL_ZERO());
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::affine2d::rotation_from_normal */
- static int TclCmd_affine2d_rotation_from_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- double nx,ny,angle;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "nx ny");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&nx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ny)) return TCL_ERROR;
- angle=atan2(ny,nx);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(-sin(angle)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cos(angle)));
- Tcl_ListObjAppendElement(interp,pResult,ODIE_REAL_ZERO());
- Tcl_ListObjAppendElement(interp,pResult,ODIE_REAL_ZERO());
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::compare */
- static int TclCmd_affine4x4_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B;
- int c;
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_affine,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_affine,&B)) return TCL_ERROR;
- c=affine_Compare(A->matrix,B->matrix);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::identity */
- static int TclCmd_affine4x4_identity(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description: Pushes an affine identity matrix onto the stack
- */
- Odie_MatrixObj *C;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Identity(C->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::translation */
- static int TclCmd_affine4x4_translation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Convert a displacement vector (X Y Z) into an affine transformation
- */
- Odie_MatrixObj *A,*C;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "VECTORXYZ" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Translation(C->matrix,A->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::scale */
- static int TclCmd_affine4x4_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Convert a scale vector (X Y Z) into an affine transformation
- */
- Odie_MatrixObj *A,*C;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "VECTORXYZ" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Scale(C->matrix,A->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::rotate_nutation */
- static int TclCmd_affine4x4_rotate_nutation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double theta;
- Odie_MatrixObj *RESULT;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "RADIANS" );
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&theta)) return TCL_ERROR;
- RESULT=Odie_MatrixObj_Create(MATFORM_affine);
- affine_rotate_nutation(RESULT->matrix,theta);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::rotate_precession */
- static int TclCmd_affine4x4_rotate_precession(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double phi;
- Odie_MatrixObj *RESULT;
- Tcl_Obj *pResult;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "RADIANS" );
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&phi)) return TCL_ERROR;
- RESULT=Odie_MatrixObj_Create(MATFORM_affine);
- affine_rotate_precession(RESULT->matrix,phi);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::rotate_spin */
- static int TclCmd_affine4x4_rotate_spin(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double psi;
- Odie_MatrixObj *RESULT;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "RADIANS" );
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&psi)) return TCL_ERROR;
- RESULT=Odie_MatrixObj_Create(MATFORM_affine);
- affine_rotate_spin(RESULT->matrix,psi);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::from_euler */
- static int TclCmd_affine4x4_from_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Convert a rotation vector (X Y Z) into an affine transformation
- */
- Odie_MatrixObj *A,*C;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "EULER" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_euler,&A)) return TCL_ERROR;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- affine_Rotate_From_Euler(C->matrix,A->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::multiply */
- static int TclCmd_affine4x4_multiply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Multiply 2 4x4 matrices. Used to combine 2 affine transformations.
- ** Note: Some affine transformations need to be performed in a particular
- ** order to make sense.
- */
- Odie_MatrixObj *A,*B,*C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_affine,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_affine,&B)) return TCL_ERROR;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Multiply(C->matrix,A->matrix,B->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::multiply_inplace */
- static int TclCmd_affine4x4_multiply_inplace(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Multiply 2 4x4 matrices. Used to combine 2 affine transformations.
- ** Note: Some affine transformations need to be performed in a particular
- ** order to make sense.
- */
- Odie_MatrixObj *A,*B,*C;
- Tcl_Obj *varname;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "VARNAME AFFINE" );
- return TCL_ERROR;
- }
- Tcl_ResetResult(interp);
- varname=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(Odie_GetMatrixFromTclObj(interp,varname,MATFORM_affine,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_affine,&B)) return TCL_ERROR;
- Odie_Affine4x4_Multiply(A->matrix,A->matrix,B->matrix);
- Tcl_InvalidateStringRep(varname);
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::inverse */
- static int TclCmd_affine4x4_inverse(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Multiply 2 4x4 matrices. Used to combine 2 affine transformations.
- ** Note: Some affine transformations need to be performed in a particular
- ** order to make sense.
- */
- Odie_MatrixObj *A,*C;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_affine,&A)) return TCL_ERROR;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Inverse(C->matrix,A->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::affine4x4::from_normal */
- static int TclCmd_affine4x4_from_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** description:
- ** Convert a displacement normal vector (X Y Z) into an affine transformation
- */
- Odie_MatrixObj *A,*C;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "VECTORXYZ" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine_From_Normal(C->matrix,A->matrix);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::bbox::create */
- static int TclCmd_odie_bbox_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *C;
- C=Odie_MatrixObj_Create(MATFORM_bbox_xy);
- VectorXY_BBOX_Reset(C->matrix);
- if(objc>1) {
- int i;
- VectorXY point;
- for(i=1;i<objc;i++) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],point)) return TCL_ERROR;
- VectorXY_BBOX_Measure(point,C->matrix);
- }
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::bbox::measure */
- static int TclCmd_odie_bbox_measure(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *C;
- Tcl_Obj *varname,*pResult;
- int i;
- VectorXY point;
- if( objc < 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BBOX VECTORXY ?VECTORXY..?");
- return TCL_ERROR;
- }
- varname=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(varname) {
- if(Odie_GetMatrixFromTclObj(interp,varname,MATFORM_bbox_xy,&C)) return TCL_ERROR;
- } else {
- C=Odie_MatrixObj_Create(MATFORM_bbox_xy);
- VectorXY_BBOX_Reset(C->matrix);
- }
- for(i=2;i<objc;i++) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],point)) return TCL_ERROR;
- VectorXY_BBOX_Measure(point,C->matrix);
- }
- pResult=Matrix_To_TclObj(C);
- Tcl_ObjSetVar2(interp,objv[1],NULL,pResult,0);
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::bbox::elements */
- static int TclCmd_odie_bbox_elements(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *C;
- Tcl_Obj *pResult;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BBOX");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_bbox_xy,&C)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(C->matrix[BBOX_X0_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(C->matrix[BBOX_Y1_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(C->matrix[BBOX_X1_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(C->matrix[BBOX_Y0_IDX]));
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::bbox::intersect */
- static int TclCmd_odie_bbox_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*B;
- int c;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BBOX BBOX");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_bbox_xy,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_bbox_xy,&B)) return TCL_ERROR;
- c=BBOX_BBOX_Intersect(A->matrix,B->matrix);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::bbox::within */
- static int TclCmd_odie_bbox_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A;
- MATOBJ *C;
- int result;
- if( objc != 3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "BBOX ?XY| X? ?y?");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_bbox_xy,&C)) return TCL_ERROR;
- if(objc==3) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- } else {
- double a1,a2;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&a1)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&a2)) return TCL_ERROR;
- A[X_IDX]=a1;
- A[Y_IDX]=a2;
- }
- result=VectorXY_Within_BBOX(A,C->matrix);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::add */
- static int TclCmd_quaternion_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetQuaternionFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- Quaternion_Add(C,A,B);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::subtract */
- static int TclCmd_quaternion_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetQuaternionFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- Quaternion_Subtract(C,A,B);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::multiply */
- static int TclCmd_quaternion_multiply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetQuaternionFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- Quaternion_Multiply(C,A,B);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::divide */
- static int TclCmd_quaternion_divide(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetQuaternionFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- Quaternion_Divide(C,A,B);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::square_root */
- static int TclCmd_quaternion_square_root(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A,C;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- Quaternion_Square_Root(C,A);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::square */
- static int TclCmd_quaternion_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A,C;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- Quaternion_Square(C,A);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::from_euler */
- static int TclCmd_quaternion_from_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- QUATERNION C;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_euler,&A)) return TCL_ERROR;
- EulerRotation_To_Quaternion(C,A->matrix[EULER_HEADING],A->matrix[EULER_ATTITUDE],A->matrix[EULER_BANK]);
- Tcl_SetObjResult(interp,Quaternion_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::rotate_by_quaternion */
- static int TclCmd_vectorxyz_rotate_by_quaternion(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A;
- VectorXYZ B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "QUATERNION VECTOR ?VECTOR ...?" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if (objc==3) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXYZ_Rotate_by_Quaternion(C,A,B);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(C));
- } else {
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- for(i=2;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],B)) return TCL_ERROR;
- VectorXYZ_Rotate_by_Quaternion(C,A,B);
- Tcl_ListObjAppendElement(interp,pResult,VectorXYZ_To_TclObj(C));
- }
- Tcl_SetObjResult(interp,pResult);
- }
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::to_euler */
- static int TclCmd_quaternion_to_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- QUATERNION A;
- VectorXYZ C;
- Odie_MatrixObj *RESULT;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetQuaternionFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- Quaternion_To_EulerRotation(C,A);
- RESULT=Odie_MatrixObj_Create(MATFORM_euler);
- RESULT->matrix[X_IDX]=A[X_IDX];
- RESULT->matrix[Y_IDX]=A[Y_IDX];
- RESULT->matrix[Z_IDX]=A[Z_IDX];
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::quaternion::from_normal */
- static int TclCmd_quaternion_from_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ FROM,TO;
- Odie_MatrixObj *RESULT;
- if(objc != 2 && objc !=3) {
- Tcl_WrongNumArgs( interp, 1, objv, "?FROM? TO" );
- return TCL_ERROR;
- }
- if(objc==2) {
- FROM[X_IDX]=0.0;
- FROM[Y_IDX]=0.0;
- FROM[Z_IDX]=-1.0;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],TO)) return TCL_ERROR;
- } else {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],FROM)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],TO)) return TCL_ERROR;
- }
- RESULT=Odie_MatrixObj_Create(MATFORM_quaternion);
- Quaternion_From_Normal(RESULT->matrix,FROM,TO);
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::tolerance */
- static int TclCmd_odie_tolerance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if(objc==2) {
- double newval;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&newval)) return TCL_ERROR;
- Vector_Set_Tolerance(newval);
- }
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(Vector_Tolerance));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::to_list */
- static int TclCmd_odie_vector_to_list(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- int idx;
- int size_a;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- size_a=A->rows*A->cols;
- Tcl_Obj **pList=NULL;
- pList=Odie_Alloc(sizeof(Tcl_Obj)*size_a);
- for(idx=0;idx<size_a;idx++) {
- pList[idx]=Tcl_NewDoubleObj(*(A->matrix+idx));
- }
- Tcl_SetObjResult(interp,Tcl_NewListObj(size_a,pList));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::index */
- static int TclCmd_odie_vector_index(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- int i=-1,j=-1,idx,n=0;
- int size_a;
- Tcl_Obj **pList=NULL;
- if(objc != 3 && objc != 4) {
- Tcl_WrongNumArgs( interp, 1, objv, "A i ?j?" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- if(Tcl_GetIntFromObj(interp,objv[2],&i)) return TCL_ERROR;
- size_a=A->rows*A->cols;
- if(i<0) {
- i=0;
- }
- if(i>=size_a) {
- i=size_a-1;
- }
- if(objc==3) {
- j=i;
- } else{
- if(Tcl_GetIntFromObj(interp,objv[3],&j)) return TCL_ERROR;
- }
- if ( j < 0 ) {
- j=size_a-1;
- } else if (j<=i) {
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(*(A->matrix+i)));
- return TCL_OK;
- }
- if(j>=size_a) {
- j=size_a-1;
- }
- n=(j-i)+1;
- pList=Odie_Alloc(sizeof(Tcl_Obj)*n);
- for(idx=i;idx<=j;idx++) {
- pList[idx]=Tcl_NewDoubleObj(*(A->matrix+idx));
- }
- Tcl_SetObjResult(interp,Tcl_NewListObj(n,pList));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::add */
- static int TclCmd_odie_vector_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B,*C;
- int i,size_c;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_null,&B)) return TCL_ERROR;
- C=Odie_Matrix_To_Fit(A,B);
- size_c=C->rows*C->cols;
- for(i=0;i<size_c;i++) {
- *(C->matrix+i) = *(A->matrix+i) + *(B->matrix+i);
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::is_null */
- static int TclCmd_odie_vector_is_null(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B,*C;
- int i,size_c;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "VECTOR" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) {
- Tcl_ResetResult(interp);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(1));
- return TCL_OK;
- }
- int size=A->rows*A->cols;
- if(size<2) {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(1));
- return TCL_OK;
- } else {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::subtract */
- static int TclCmd_odie_vector_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B,*C;
- int i,size_c;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_null,&B)) return TCL_ERROR;
- C=Odie_Matrix_To_Fit(A,B);
- size_c=C->rows*C->cols;
- for(i=0;i<size_c;i++) {
- *(C->matrix+i) = *(A->matrix+i) - *(B->matrix+i);
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::midpoint */
- static int TclCmd_odie_vector_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B,*C;
- int i,size_c;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_null,&B)) return TCL_ERROR;
- C=Odie_Matrix_To_Fit(A,B);
- size_c=C->rows*C->cols;
- for(i=0;i<size_c;i++) {
- *(C->matrix+i) = (*(A->matrix+i) - *(B->matrix+i))*0.5 + *(A->matrix+i);
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::reciprocal */
- static int TclCmd_odie_vector_reciprocal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*RESULT;
- int i;
- int size_a;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- RESULT=Odie_Matrix_To_Fit(A,A);
- size_a=A->rows*A->cols;
- for(i=0;i<size_a;i++) {
- *(RESULT->matrix+i) = 1.0 / *(A->matrix+i);
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::dot_product */
- static int TclCmd_odie_vector_dot_product(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B;
- int i;
- int size_a;
- int size_b;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_null,&B)) return TCL_ERROR;
- size_a=A->rows*A->cols;
- size_b=B->rows*B->cols;
- double result=0;
- for(i=0;i<size_a && i<size_b;i++) {
- result += *(A->matrix+i) * *(B->matrix+i);
- }
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::to_matrix */
- static int TclCmd_odie_vector_to_matrix(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::to_fuzzy */
- static int TclCmd_odie_vector_to_fuzzy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- int i,size_a;
- Tcl_Obj *pResult;
- if(objc < 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- size_a=A->rows*A->cols;
- for(i=0;i<size_a;i++) {
- Tcl_ListObjAppendElement(interp,pResult,ODIE_NewFuzzyObj(*(A->matrix+i)));
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::scale */
- static int TclCmd_odie_vector_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A,*B,*C=NULL,*RESULT;
- int i,size_a,size_b,size_c;
- if(objc!=3 && objc !=4) {
- Tcl_WrongNumArgs( interp, 1, objv, "A SCALE ?TRANSLATE?" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_null,&B)) return TCL_ERROR;
- size_a=A->rows*A->cols;
- size_b=B->rows*B->cols;
- if(size_b > 1 && size_b!=size_a) {
- Tcl_AppendResult(interp, "B is not a scaler, or arguments are not of the same size", 0);
- return TCL_ERROR;
- }
- if(objc==4) {
- if(Odie_GetMatrixFromTclObj(interp,objv[3],MATFORM_null,&C)) return TCL_ERROR;
- size_c=C->rows*C->cols;
- if(size_c!=size_a) {
- Tcl_AppendResult(interp, "TRANS is not the same size", 0);
- return TCL_ERROR;
- }
- }
- RESULT=Odie_Matrix_Duplicate(A);
- if(size_b==1) {
- double scaler=*(B->matrix+0);
- for(i=0;i<size_a;i++) {
- *(RESULT->matrix+i) *= scaler;
- }
- } else {
- for(i=0;i<size_a;i++) {
- *(RESULT->matrix+i) *= *(B->matrix+i);
- }
- }
- if(C) {
- for(i=0;i<size_a;i++) {
- *(RESULT->matrix+i) -= *(C->matrix+i);
- }
- }
- Tcl_SetObjResult(interp,Matrix_To_TclObj(RESULT));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::length */
- static int TclCmd_odie_vector_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,size;
- Odie_MatrixObj *A;
- double result,sum=0.0;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "vector");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- size=A->rows*A->cols;
- result=0.0;
- for(i=1;i<size;i++) {
- double a=*(A->matrix+1);
- sum+=a*a;
- }
- result=sqrt(sum);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::vector::length_squared */
- static int TclCmd_odie_vector_length_squared(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,size;
- Odie_MatrixObj *A;
- double result,sum=0.0;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "vector");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- size=A->rows*A->cols;
- result=0.0;
- for(i=1;i<size;i++) {
- double a=*(A->matrix+1);
- sum+=a*a;
- }
- result=sum;
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::odie::grid */
- static int TclCmd_odie_grid(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double grid,grain;
- int gridint,i,asint=0;
- Tcl_Obj *pResult;
- if( objc < 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "grid DBL ...");
- return TCL_ERROR;
- }
- asint=1;
- if(Tcl_GetIntFromObj(interp,objv[1],&gridint)) {
- asint=0;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- } else {
- grid=(double)gridint;
- }
- pResult=Tcl_NewObj();
- grain=grid*0.5;
- for(i=2;i<objc;i++) {
- double thisval,remainder;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&thisval)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- thisval=Vector_GridScaler(thisval,grid,grain);
- if(asint) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(thisval));
- } else {
- remainder=fmod(thisval,grid);
- Tcl_ListObjAppendElement(interp, pResult, ODIE_NewFuzzyObj(thisval-remainder));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::odie::gridvar */
- static int TclCmd_odie_gridvar(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double grid,grain,val;
- int gridint,i,asint=0;
- if( objc < 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize DBLVAR ...");
- return TCL_ERROR;
- }
- asint=1;
- if(Tcl_GetIntFromObj(interp,objv[1],&gridint)) {
- asint=0;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- } else {
- grid=(double)gridint;
- }
- grain=grid*0.5;
- for(i=2;i<objc;i++) {
- double thisval,remainder;
- Tcl_Obj *varname;
- varname=Tcl_ObjGetVar2(interp,objv[i],NULL,0);
- if(varname==NULL) continue;
- if(Tcl_GetDoubleFromObj(interp,varname,&val)) continue;
- thisval=Vector_GridScaler(val,grid,grain);
- if(asint) {
- Tcl_ObjSetVar2(interp,objv[i],NULL,Tcl_NewIntObj(thisval),0);
- } else {
- remainder=fmod(thisval,grid);
- Tcl_ObjSetVar2(interp,objv[i],NULL,ODIE_NewFuzzyObj(thisval-remainder),0);
- }
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::compare */
- static int TclCmd_vector2d_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B;
- int c;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- c=VectorXY_SamePoint(A,B);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::add */
- static int TclCmd_vector2d_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, P;
- Tcl_Obj *pResult;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- VectorXY_Add(P,A,B);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Y_IDX]));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::subtract */
- static int TclCmd_vector2d_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, P;
- Tcl_Obj *pResult;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- VectorXY_Subtract(P,A,B);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Y_IDX]));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::midpoint */
- static int TclCmd_vector2d_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, P;
- Tcl_Obj *pResult;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- VectorXY_Midpoint(P,A,B);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Y_IDX]));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::affine_apply */
- static int TclCmd_vector2d_affine_apply(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- int i;
- double matA[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
- if( objc < 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "matrix x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- for(i=0;i<6;i++) {
- Tcl_Obj *temp;
- if(Tcl_ListObjIndex(interp, objv[1], i, &temp)) return TCL_ERROR;
- if(Odie_GetMatrixElementFromObj(interp,temp,matA,i)) return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- for(i=2;i<objc;i+=2) {
- double x,y,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- newx=matA[0]*x+matA[1]*y+matA[4];
- newy=matA[2]*x+matA[3]*y+matA[5];
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::angle */
- static int TclCmd_vector2d_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], P, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], P, Y_IDX) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(VectorXY_Angle_Three_Point(A, B, P)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::distance */
- static int TclCmd_vector2d_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double result,ax,ay,bx,by,dx,dy;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x0 y0 x1 y1");
- return TCL_ERROR;
- }
- result=0.0;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&ax)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ay)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&bx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&by)) return TCL_ERROR;
- dx=bx-ax;
- dy=by-ay;
- result=sqrt(dx*dx + dy*dy);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::dotproduct */
- static int TclCmd_vector2d_dotproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], P, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], P, Y_IDX) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(VectorXY_Dot_Product(A, B, P)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::crossproduct */
- static int TclCmd_vector2d_crossproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], P, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], P, Y_IDX) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(VectorXY_crossProduct(A, B, P)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::rightof */
- static int TclCmd_vector2d_rightof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** tclcmd: triag_test_rightof X0 Y0 X1 Y1 X2 Y2
- **
- ** A TCL command for testing the rightOf() function.
- */
- VectorXY A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], P, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], P, Y_IDX) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewIntObj(VectorXY_BendDirection(A, B, P)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::rotate_and_size */
- static int TclCmd_vector2d_rotate_and_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult;
- int i;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double nx,ny,scalex,scaley,angle;
- if( objc < 7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "normalx normaly sizex sizey x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&nx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ny)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&scalex)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&scaley)) return TCL_ERROR;
- angle=atan2(ny,nx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- scalex*=0.5;
- scaley*=0.5;
- pResult=Tcl_NewObj();
- for(i=5;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- sx=x*scalex;
- sy=y*scaley;
- newx=matA[0]*sx+matA[1]*sy+matA[4];
- newy=matA[2]*sx+matA[3]*sy+matA[5];
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::scale */
- static int TclCmd_vector2d_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- int i;
- double scalex,scaley;
- if( objc < 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "sizex sizey x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&scalex)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&scaley)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- scalex*=0.5;
- scaley*=0.5;
- for(i=3;i<objc;i+=2) {
- double x,y,sx,sy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- sx=x*scalex;
- sy=y*scaley;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(sy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::translate_and_zoom */
- static int TclCmd_vector2d_translate_and_zoom(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult;
- int i;
- double zoom;
- double centerx,centery;
- if( objc < 6 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=4;i<objc;i+=2) {
- double x,y,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- newx=(x/zoom)+centerx;
- newy=(y/zoom)+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::point_on_segment */
- static int TclCmd_vector2d_point_on_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x1,y1,x2,y2,x3,y3;
- if( objc != 7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "point_on_segment x y x1 y1 x2 y2");
- return TCL_ERROR;
- }
- if (Tcl_GetDoubleFromObj(interp,objv[1],&x1)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[2],&y1)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[3],&x2)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[4],&y2)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[5],&x3)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[6],&y3)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewIntObj(Vector2d_PointIsOnSegment(x1,y1,x2,y2,x3,y3)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::line_circle_intersect */
- static int TclCmd_vector2d_line_circle_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double ax1,ax2,ay1,ay2;
- double bx1,by1,brad;
- double ix,iy;
- if(objc<8) {
- Tcl_WrongNumArgs(interp, 1, objv, "ax1 ay1 ax2 ay2 bx1 by1 brad");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &ax1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &ay1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &ax2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &ay2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &bx1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &by1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[7], &brad) ) return TCL_ERROR;
- if(ODIE_Math_LineCircleIntersect(ax1,ay1,ax2,ay2,bx1,by1,brad,&ix,&iy)) {
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ix));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(iy));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::line_intersect */
- static int TclCmd_vector2d_line_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double ax1,ax2,ay1,ay2;
- double bx1,bx2,by1,by2;
- double ix,iy;
- if(objc<9) {
- Tcl_WrongNumArgs(interp, 1, objv, "ax1 ay1 ax2 ay2 bx1 by1 bx2 by2");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &ax1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &ay1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &ax2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &ay2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &bx1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &by1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[7], &bx2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[8], &by2) ) return TCL_ERROR;
- if(ODIE_Math_LineLineIntersect(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2,&ix,&iy)) {
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ix));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(iy));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::line_overlap */
- static int TclCmd_vector2d_line_overlap(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- double ax1,ax2,ay1,ay2;
- double bx1,bx2,by1,by2;
- if(objc<9) {
- Tcl_WrongNumArgs(interp, 1, objv, "ax1 ay1 ax2 ay2 bx1 by1 bx2 by2");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &ax1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &ay1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &ax2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &ay2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &bx1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &by1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[7], &bx2) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[8], &by2) ) return TCL_ERROR;
- /*
- ** ignore if the segments connect at endpoints
- if(ax1==bx1 && ay1==by1) return TCL_OK;
- if(ax1==bx2 && ay1==by2) return TCL_OK;
- if(ax2==bx1 && ay2==by1) return TCL_OK;
- if(ax2==bx2 && ay2==by2) return TCL_OK;
- */
- pResult = Tcl_NewIntObj(Vector2d_LineLineCoincident(ax1,ay1,ax2,ay2,bx1,by1,bx2,by2));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector2d::colinear */
- static int TclCmd_vector2d_colinear(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x1,y1,x2,y2,x3,y3;
- if( objc != 7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "colinear x1 y1 x2 y2 x3 y3");
- return TCL_ERROR;
- }
- if (Tcl_GetDoubleFromObj(interp,objv[1],&x1)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[2],&y1)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[3],&x2)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[4],&y2)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[5],&x3)) return TCL_ERROR;
- if (Tcl_GetDoubleFromObj(interp,objv[6],&y3)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Vector2d_IsColinear(x1,y1,x2,y2,x3,y3)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector3d::compare */
- static int TclCmd_vector3d_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B;
- int c;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], A, Z_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], B, Z_IDX) ) return TCL_ERROR;
- c=VectorXYZ_SamePoint(A,B);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vector3d::add */
- static int TclCmd_vector3d_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A, B, P;
- Tcl_Obj *pResult;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], A, Z_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], B, Z_IDX) ) return TCL_ERROR;
- VectorXYZ_Add(P,A,B);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Y_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Z_IDX]));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector3d::subtract */
- static int TclCmd_vector3d_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A, B, P;
- Tcl_Obj *pResult;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], A, Z_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], B, Z_IDX) ) return TCL_ERROR;
- VectorXYZ_Subtract(P,A,B);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Y_IDX]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(P[Z_IDX]));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vector3d::orthagonal */
- static int TclCmd_vector3d_orthagonal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int result;
- VectorXY A, B;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], A, Z_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], B, Z_IDX) ) return TCL_ERROR;
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(VectorXYZ_IsOrthagonal(A,B)));
- return TCL_OK;
- }
- /* Tcl Proc ::vector3d::distance */
- static int TclCmd_vector3d_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double result;
- VectorXY A, B;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], A, Z_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], B, Z_IDX) ) return TCL_ERROR;
- result=VectorXYZ_Distance(A,B);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vector3d::distanceSq */
- static int TclCmd_vector3d_distanceSq(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double result;
- VectorXY A, B;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if( Odie_GetMatrixElementFromObj(interp, objv[1], A, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[2], A, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[3], A, Z_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[4], B, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], B, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], B, Z_IDX) ) return TCL_ERROR;
- result=VectorXYZ_DistanceSq(A,B);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorN::length */
- static int TclCmd_vectorN_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- double result,sum=0.0;
- if( objc<1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "x ?y? ?z? ?...?");
- return TCL_ERROR;
- }
- result=0.0;
- for(i=1;i<objc;i++) {
- double a;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&a)) return TCL_ERROR;
- sum+=a*a;
- }
- result=sqrt(sum);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorN::distance */
- static int TclCmd_vectorN_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- double result;
- if( objc<1 ){
- Tcl_WrongNumArgs(interp, 1, objv, "i1 i2 ?j1 j2? ?k1 k2?");
- return TCL_ERROR;
- }
- result=0.0;
- for(i=1;i<objc;i+=2) {
- double a,b,dx;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&a)) return TCL_ERROR;
- if(i+1>=objc) {
- Tcl_AppendResult(interp, "Odd number of arguments",(char*)0);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&b)) return TCL_ERROR;
- dx=b-a;
- result=result+dx*dx;
- }
- result=sqrt(result);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorN::scale */
- static int TclCmd_vectorN_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- double scale;
- Tcl_Obj *pResult;
- if( objc<3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "SCALE X Y Z");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&scale)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=2;i<objc;i++) {
- double a,b,dx;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&a)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- Tcl_ListObjAppendElement(interp,pResult,ODIE_NewFuzzyObj(a*scale));
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorN::scalevar */
- static int TclCmd_vectorN_scalevar(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double scale,val;
- int scaleint,i,asint=0;
- if( objc < 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "scalesize DBLVAR ...");
- return TCL_ERROR;
- }
- asint=1;
- if(Tcl_GetIntFromObj(interp,objv[1],&scaleint)) {
- asint=0;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&scale)) return TCL_ERROR;
- } else {
- scale=(double)scaleint;
- }
- for(i=2;i<objc;i++) {
- double thisval,remainder;
- Tcl_Obj *varname;
- varname=Tcl_ObjGetVar2(interp,objv[i],NULL,0);
- if(varname==NULL) continue;
- if(Tcl_GetDoubleFromObj(interp,varname,&val)) continue;
- thisval=scale*val;
- if(asint) {
- Tcl_ObjSetVar2(interp,objv[i],NULL,Tcl_NewIntObj(thisval),0);
- } else {
- remainder=fmod(thisval,scale);
- Tcl_ObjSetVar2(interp,objv[i],NULL,ODIE_NewFuzzyObj(thisval-remainder),0);
- }
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::compare */
- static int TclCmd_vectorxy_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B;
- int c;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- c=VectorXY_SamePoint(A,B);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::add */
- static int TclCmd_vectorxy_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXY_Add(C,A,B);
- Tcl_SetObjResult(interp,VectorXY_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::subtract */
- static int TclCmd_vectorxy_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXY_Subtract(C,A,B);
- Tcl_SetObjResult(interp,VectorXY_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::midpoint */
- static int TclCmd_vectorxy_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXY_Midpoint(C,A,B);
- Tcl_SetObjResult(interp,VectorXY_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::add_stream */
- static int TclCmd_vectorxy_add_stream(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A,B,C;
- int i,n;
- Tcl_Obj *pObj,*pResult;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A BLIST" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- pResult=Tcl_NewListObj(0,NULL);
- for(i=0; i<n; i++){
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if(Odie_GetVectorXYFromTclObj(interp,pObj,B)) return TCL_ERROR;
- VectorXY_Add(C,A,B);
- Tcl_ListObjAppendElement(0, pResult, VectorXY_To_TclObj(C));
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::angle */
- static int TclCmd_vectorxy_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, C;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B C");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[3],C)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(VectorXY_Angle_Three_Point(A, B, C)));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::create */
- static int TclCmd_vectorxy_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A;
- double x;
- Tcl_Obj *pResult;
- if(objc != 2 && objc !=3) {
- Tcl_WrongNumArgs( interp, 1, objv, "LIST\nor\nx y" );
- return TCL_ERROR;
- }
- if(objc==2) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- } else {
- int i;
- for(i=0;i<2;i++) {
- if(Tcl_GetDoubleFromObj(interp,objv[1+i],&x)) return TCL_ERROR;
- A[i]=x;
- }
- }
- pResult=VectorXY_To_TclObj(A);
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::toint */
- static int TclCmd_vectorxy_toint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A;
- double x;
- Tcl_Obj *pResult;
- int i;
- if(objc != 2 && objc !=4) {
- Tcl_WrongNumArgs( interp, 1, objv, "LIST\nor\nx y" );
- return TCL_ERROR;
- }
- if(objc==2) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- } else {
- for(i=0;i<2;i++) {
- if(Tcl_GetDoubleFromObj(interp,objv[1+i],&A[i])) return TCL_ERROR;
- }
- }
- pResult=Tcl_NewObj();
- for(i=0;i<2;i++) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj((int)A[i]));
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::crossproduct */
- static int TclCmd_vectorxy_crossproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** tclcmd: vectorxy crossproduct A B C
- ** Return the the cross product of AB*BC
- */
- VectorXY A, B, C;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B C");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[3],C)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(VectorXY_crossProduct(A, B, C)));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::distance */
- static int TclCmd_vectorxy_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VECTORXY A,B;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- double result=0.0,dx,dy;
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- dx=B[X_IDX]-A[X_IDX];
- dy=B[Y_IDX]-A[Y_IDX];
- result=sqrt(dx*dx + dy*dy);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::length */
- static int TclCmd_vectorxy_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VECTORXY A;
- double result=0.0;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- result=sqrt(A[X_IDX]*A[X_IDX] + A[Y_IDX]*A[Y_IDX]);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::normalize */
- static int TclCmd_vectorxy_normalize(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- VectorXY_Normalize(A);
- Tcl_SetObjResult(interp,VectorXY_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::dotproduct */
- static int TclCmd_vectorxy_dotproduct(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXY A, B, C;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B C");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[3],C)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(VectorXY_Dot_Product(A, B, C)));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::rightof */
- static int TclCmd_vectorxy_rightof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** tclcmd: triag_test_rightof X0 Y0 X1 Y1 X2 Y2
- **
- ** A TCL command for testing the rightOf() function.
- */
- VectorXY A, B, C;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[3],C)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewIntObj(VectorXY_BendDirection(A, B, C)));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::rotate_and_size */
- static int TclCmd_vectorxy_rotate_and_size(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult;
- int i;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double nx,ny,scalex,scaley,angle;
- if( objc < 7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "normalx normaly sizex sizey V ?V?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&nx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&ny)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&scalex)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&scaley)) return TCL_ERROR;
- angle=atan2(ny,nx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- scalex*=0.5;
- scaley*=0.5;
- pResult=Tcl_NewObj();
- for(i=5;i<objc;i++) {
- double sx,sy;
- VECTORXY A,B;
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],A)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- sx=A[X_IDX] * scalex;
- sy=A[Y_IDX] * scaley;
- B[X_IDX]=matA[0]*sx+matA[1]*sy+matA[4];
- B[Y_IDX]=matA[2]*sx+matA[3]*sy+matA[5];
- Tcl_ListObjAppendElement(interp,pResult,VectorXY_To_TclObj(B));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::scale */
- static int TclCmd_vectorxy_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- int i;
- double scalex,scaley;
- if( objc < 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "sizex sizey V ?V...?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&scalex)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&scaley)) return TCL_ERROR;
- scalex*=0.5;
- scaley*=0.5;
- pResult=Tcl_NewObj();
- for(i=3;i<objc;i+=2) {
- double x,y;
- VECTORXY A,B;
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],A)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- x=A[X_IDX];
- y=A[Y_IDX];
- B[X_IDX]=x*scalex;
- B[Y_IDX]=y*scaley;
- Tcl_ListObjAppendElement(interp,pResult,VectorXY_To_TclObj(B));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::translate_and_zoom */
- static int TclCmd_vectorxy_translate_and_zoom(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult;
- int i;
- double zoom;
- VECTORXY center;
- if( objc < 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom CENTER V ?V...?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Odie_GetVectorXYFromTclObj(interp,objv[2],center)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=3;i<objc;i++) {
- VECTORXY A,B;
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],A)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- B[X_IDX]=(A[X_IDX]/zoom)+center[X_IDX];
- B[Y_IDX]=(A[Y_IDX]/zoom)+center[Y_IDX];
- Tcl_ListObjAppendElement(interp,pResult,VectorXY_To_TclObj(B));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxy::flatten */
- static int TclCmd_vectorxy_flatten(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ point;
- int i,j;
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- if(objc==2) {
- Tcl_Obj **rowPtrs;
- int rows;
- if(Tcl_ListObjGetElements(interp, objv[1], &rows, &rowPtrs)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- for(j=0;j<rows;j++) {
- if(Odie_GetVectorXYFromTclObj(interp,rowPtrs[j],point)) return TCL_ERROR;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[Y_IDX]));
- }
- } else {
- for(i=1;i<objc;i++) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],point)) return TCL_ERROR;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[Y_IDX]));
- }
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::scale */
- static int TclCmd_vectorxyz_scale(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,C;
- double b;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&b)) return TCL_ERROR;
- VectorXYZ_Copy(C,A);
- VectorXYZ_Scale(C,b);
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::zero */
- static int TclCmd_vectorxyz_zero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- VectorXYZ_Zero(A);
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::compare */
- static int TclCmd_vectorxyz_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A, B;
- int c;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- c=VectorXYZ_SamePoint(A,B);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::polygon_normal_compare */
- static int TclCmd_vectorxyz_polygon_normal_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A, B;
- int c;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- c=1;
- if((fabs(A[X_IDX])-fabs(B[X_IDX]))>0.1) c=0;
- if((fabs(A[Y_IDX])-fabs(B[Y_IDX]))>0.1) c=0;
- if((fabs(A[Z_IDX])-fabs(B[Z_IDX]))>0.1) c=0;
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::create */
- static int TclCmd_vectorxyz_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- double x;
- Tcl_Obj *pResult;
- if(objc != 2 && objc !=4) {
- Tcl_WrongNumArgs( interp, 1, objv, "LIST\nor\nx y z" );
- return TCL_ERROR;
- }
- if(objc==2) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- } else {
- int i;
- for(i=0;i<3;i++) {
- if(Tcl_GetDoubleFromObj(interp,objv[1+i],&x)) return TCL_ERROR;
- A[i]=x;
- }
- }
- pResult=VectorXYZ_To_TclObj(A);
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::toint */
- static int TclCmd_vectorxyz_toint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- double x;
- Tcl_Obj *pResult;
- int i;
- if(objc != 2 && objc !=5) {
- Tcl_WrongNumArgs( interp, 1, objv, "LIST\nor\nx y z" );
- return TCL_ERROR;
- }
- if(objc==2) {
- if(Odie_GetVectorXYFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- } else {
- for(i=0;i<3;i++) {
- if(Tcl_GetDoubleFromObj(interp,objv[1+i],&A[i])) return TCL_ERROR;
- }
- }
- pResult=Tcl_NewObj();
- for(i=0;i<3;i++) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj((int)A[i]));
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::add */
- static int TclCmd_vectorxyz_add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXYZ_Add(C,A,B);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::add_inplace */
- static int TclCmd_vectorxyz_add_inplace(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- VectorXYZ B;
- Tcl_Obj *varname;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- varname=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(varname==NULL) {
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,varname,MATFORM_vectorxyz,&A)) return TCL_ERROR;
- Tcl_ResetResult(interp);
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXYZ_Add(A->matrix,A->matrix,B);
- Tcl_InvalidateStringRep(varname);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::orthagonal */
- static int TclCmd_vectorxyz_orthagonal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int result;
- VectorXY A, B;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 Z0 X1 Y1 Z1");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(VectorXYZ_IsOrthagonal(A,B)));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::subtract */
- static int TclCmd_vectorxyz_subtract(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXYZ_Subtract(C,A,B);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::midpoint */
- static int TclCmd_vectorxyz_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXYZ_Midpoint(C,A,B);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::cross_product */
- static int TclCmd_vectorxyz_cross_product(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- VectorXYZ_Cross_Product(C,A,B);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(C));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::dot_product */
- static int TclCmd_vectorxyz_dot_product(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B;
- double result;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- result=VectorXYZ_Dot_Product(A,B);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::transform */
- static int TclCmd_vectorxyz_transform(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *Affine;
- VectorXYZ A,C;
- int i,n;
- n=objc-2;
- Tcl_Obj **pArray;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "affine vector ?vector...?" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_affine,&Affine)) return TCL_ERROR;
- if(objc==3) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- VectorXYZ_MatrixMultiply(C,A,Affine->matrix);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(C));
- return TCL_OK;
- }
- pArray=(Tcl_Obj **)ckalloc(sizeof(Tcl_Obj)*n);
- for(i=0;i<n;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2+i],A)) return TCL_ERROR;
- VectorXYZ_MatrixMultiply(C,A,Affine->matrix);
- pArray[i]=VectorXYZ_To_TclObj(C);
- }
- Tcl_SetObjResult(interp,Tcl_NewListObj(n,pArray));
- ckfree((char *)pArray);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::length */
- static int TclCmd_vectorxyz_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- double result;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- result=VectorXYZ_Magnitude(A);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::distance */
- static int TclCmd_vectorxyz_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B;
- double result;
- if(objc != 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- result=VectorXYZ_Distance(A,B);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::distanceSq */
- static int TclCmd_vectorxyz_distanceSq(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B;
- double result;
- if(objc != 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- result=VectorXYZ_DistanceSq(A,B);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::length_inv_sqr */
- static int TclCmd_vectorxyz_length_inv_sqr(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- double result;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- result=VectorXYZ_MagnitudeInvSqr(A);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::normalize */
- static int TclCmd_vectorxyz_normalize(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- if(objc != 2) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- /* This is save because Odie_GetVectorXYZFromTclObj copies values and
- ** doesn't redirect to the point in memory where the value actually lives
- */
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- VectorXYZ_Normalize(A);
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::point_on_segment */
- static int TclCmd_vectorxyz_point_on_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,X;
- if( objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "point_on_segment X A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],X)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],B)) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewIntObj(VectorXYZ_PointIsOnSegment(X,A,B)));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::point_on_segment_x */
- static int TclCmd_vectorxyz_point_on_segment_x(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,X;
- VectorXYZ v1, v2;
- double t;
- if( objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "point_on_segment_x X A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],X)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],B)) return TCL_ERROR;
- VectorXYZ_Subtract(v1, X, A);
- VectorXYZ_Subtract(v2, B, A);
- if(VectorXYZ_DistanceSq(v1,v2)<Vector_Tolerance_Sq) {
- /* X, A, and B are all the same point */
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(0.5));
- return TCL_OK;
- }
- t = VectorXYZ_Dot_Product(v1, v2)/VectorXYZ_MagnitudeSq(v2);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(t));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::axis_of_normal */
- static int TclCmd_vectorxyz_axis_of_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A;
- int axis;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "axis_of_normal X");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- axis=VectorXYZ_AxisOfNormal(A);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(axis));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::bend_direction */
- static int TclCmd_vectorxyz_bend_direction(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C;
- int result;
- if(objc != 4) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],C)) return TCL_ERROR;
- result=VectorXYZ_BendDirection(A,B,C);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::angle_three_points */
- static int TclCmd_vectorxyz_angle_three_points(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,C,normal;
- double result;
- if(objc != 4 && objc != 5) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C ?normal?" );
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],C)) return TCL_ERROR;
- if(objc==5) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[4],normal)) return TCL_ERROR;
- } else {
- VectorXYZ_Normal_of_Three_Points(normal,A,B,C);
- }
- result=VectorXYZ_Angle_Three_Point(A,B,C,normal);
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::colinear */
- static int TclCmd_vectorxyz_colinear(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,c;
- VectorXYZ P[3];
- if(objc != 4) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C" );
- return TCL_ERROR;
- }
- for(i=0;i<3;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1+i],P[i])) return TCL_ERROR;
- }
- c=VectorXYZ_IsColinear(P[0],P[1],P[2]);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::coplaner */
- static int TclCmd_vectorxyz_coplaner(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,c;
- VectorXYZ P[3],Q;
- if(objc < 5) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C D ..." );
- return TCL_ERROR;
- }
- for(i=0;i<3;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1+i],P[i])) return TCL_ERROR;
- }
- for(i=4;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],Q)) return TCL_ERROR;
- if(!VectorXYZ_IsCoplaner(P[0],P[1],P[2],Q)) {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- }
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(1));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::linelinecoincident_int */
- static int TclCmd_vectorxyz_linelinecoincident_int(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,c;
- VectorXYZ P[4];
- VectorXYZ ICEPT[2];
- if(objc != 5) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C D" );
- return TCL_ERROR;
- }
- for(i=0;i<4;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1+i],P[i])) return TCL_ERROR;
- }
- c=VectorXYZ_LineLineCoincident(P[0],P[1],P[2],P[3],ICEPT[0],ICEPT[1]);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::linelinecoincident */
- static int TclCmd_vectorxyz_linelinecoincident(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,c;
- VectorXYZ P[4];
- VectorXYZ ICEPT[2];
- if(objc != 5) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C D" );
- return TCL_ERROR;
- }
- for(i=0;i<4;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1+i],P[i])) return TCL_ERROR;
- }
- c=VectorXYZ_LineLineCoincident(P[0],P[1],P[2],P[3],ICEPT[0],ICEPT[1]);
- if(c>0) {
- Tcl_Obj *pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(c));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(ICEPT[0]));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(ICEPT[1]));
- Tcl_SetObjResult(interp,pResult);
- } else {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(c));
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::linelineintersect */
- static int TclCmd_vectorxyz_linelineintersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,c;
- VectorXYZ P[4];
- VectorXYZ PA,PB;
- double mua,mub;
- Tcl_Obj *pResult;
- if(objc != 5) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C D" );
- return TCL_ERROR;
- }
- for(i=0;i<4;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1+i],P[i])) return TCL_ERROR;
- }
- c=VectorXYZ_LineLineIntersect(P[0],P[1],P[2],P[3],PA,PB,&mua,&mub);
- if(c==0) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(c<=0) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(mua>=1.0 || mua<=0.0) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(mub>=1.0 || mub<=0.0) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(PA));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(PB));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(mua));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(mub));
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::linelineintersect_distance */
- static int TclCmd_vectorxyz_linelineintersect_distance(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,c;
- VectorXYZ P[4];
- VectorXYZ PA,PB;
- double mua,mub;
- Tcl_Obj *pResult;
- if(objc != 5) {
- Tcl_WrongNumArgs( interp, 1, objv, "A B C D" );
- return TCL_ERROR;
- }
- for(i=0;i<4;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1+i],P[i])) return TCL_ERROR;
- }
- c=VectorXYZ_LineLineIntersect(P[0],P[1],P[2],P[3],PA,PB,&mua,&mub);
- if(c==0) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(c<=0) {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(c));
- return TCL_OK;
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(PA));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(PB));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(mua));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(mub));
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::sizeof */
- static int TclCmd_vectorxyz_sizeof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(sizeof(VectorXYZ)));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(X_IDX));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(Y_IDX));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(Z_IDX));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(QW_IDX));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(QX_IDX));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(QY_IDX));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(QZ_IDX));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::closest_point_on_segment */
- static int TclCmd_vectorxyz_closest_point_on_segment(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ A,B,R,X;
- if(objc!=4) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B X");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],B)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],X)) return TCL_ERROR;
- VectorXYZ_ClosestPointOnSegment(A,B,X,R);
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(R));
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::point_in_triangle */
- static int TclCmd_vectorxyz_point_in_triangle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ TA,TB,TC,POINT,LA,LB,INTERSECT,normal,center;
- double t,d1,d2;
- if(objc!=5) {
- Tcl_WrongNumArgs(interp, 1, objv, "TA TB TC POINT");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],TA)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],TB)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],TC)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[4],POINT)) return TCL_ERROR;
- center[X_IDX] = (TA[X_IDX]+TB[X_IDX]+TC[X_IDX])/3.0;
- center[Y_IDX] = (TA[X_IDX]+TB[Y_IDX]+TC[Y_IDX])/3.0;
- center[Z_IDX] = (TA[Z_IDX]+TB[Z_IDX]+TC[Z_IDX])/3.0;
- VectorXYZ_Normal_of_Three_Points(normal,TA,TB,TC);
- d1 = VectorXYZ_Distance(POINT, center)*2;
- d2 = normal[X_IDX]*d1;
- LA[X_IDX] = POINT[X_IDX] + d2;
- LB[X_IDX] = POINT[X_IDX] - d2;
- d2 = normal[Y_IDX]*d1;
- LA[Y_IDX] = POINT[Y_IDX] + d2;
- LB[Y_IDX] = POINT[Y_IDX] - d2;
- d2 = normal[Z_IDX]*d1;
- LA[Z_IDX] = POINT[Z_IDX] + d2;
- LB[Z_IDX] = POINT[Z_IDX] - d2;
- t=VectorXYZ_TriangleLineIntersect(TA,TB,TC,LA,LB,INTERSECT);
- if(t<0) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- d1=VectorXYZ_DistanceSq(POINT,INTERSECT);
- if(d1<=Vector_Tolerance_Sq) {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(1));
- } else {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(0));
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::triangle_line_intersect */
- static int TclCmd_vectorxyz_triangle_line_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ TA,TB,TC,LA,LB,INTERSECT;
- double t;
- Tcl_Obj *pResult;
- if(objc!=6) {
- Tcl_WrongNumArgs(interp, 1, objv, "TA TB TC LA LB");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],TA)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],TB)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],TC)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[4],LA)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[5],LB)) return TCL_ERROR;
- t=VectorXYZ_TriangleLineIntersect(TA,TB,TC,LA,LB,INTERSECT);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(t));
- if(t>=0) {
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(INTERSECT));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::line_sphere_intersect_length */
- static int TclCmd_vectorxyz_line_sphere_intersect_length(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*B,*C;
- double brad;
- double ix,iy;
- if(objc<5) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B C brad");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_vectorxyz,&B)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[3],MATFORM_vectorxyz,&C)) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &brad) ) return TCL_ERROR;
- if(!VectorXYZ_LineSphereIntersect(
- A->matrix[X_IDX],A->matrix[Y_IDX],A->matrix[Z_IDX],
- B->matrix[X_IDX],B->matrix[Y_IDX],B->matrix[Z_IDX],
- C->matrix[X_IDX],C->matrix[Y_IDX],C->matrix[Z_IDX],
- brad,&ix,&iy)) {
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(0.0));
- return TCL_OK;
- }
- if(ix>=0.0 && ix <= 1.0 && iy>=0.0 && iy <= 1.0) {
- double dx,dy,dz,len;
- dx=B->matrix[X_IDX]-A->matrix[X_IDX];
- dy=B->matrix[Y_IDX]-A->matrix[Y_IDX];
- dz=B->matrix[Z_IDX]-A->matrix[Z_IDX];
- len=sqrt(dx*dx+dy*dy+dz*dz);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(len*fabs(iy-ix)));
- } else {
- /* Intersection outside of segment or tangental to segment*/
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(0.0));
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::line_sphere_intersect_area */
- static int TclCmd_vectorxyz_line_sphere_intersect_area(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*B,*C;
- double brad;
- double ix,iy;
- if(objc<5) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B C brad");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_vectorxyz,&B)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[3],MATFORM_vectorxyz,&C)) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &brad) ) return TCL_ERROR;
- if(!VectorXYZ_LineSphereIntersect(
- A->matrix[X_IDX],A->matrix[Y_IDX],A->matrix[Z_IDX],
- B->matrix[X_IDX],B->matrix[Y_IDX],B->matrix[Z_IDX],
- C->matrix[X_IDX],C->matrix[Y_IDX],C->matrix[Z_IDX],
- brad,&ix,&iy)) {
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(0.0));
- return TCL_OK;
- }
- if(ix>=0.0 && ix <= 1.0 && iy>=0.0 && iy <= 1.0) {
- double dx,dy,dz,len;
- dx=B->matrix[X_IDX]-A->matrix[X_IDX];
- dy=B->matrix[Y_IDX]-A->matrix[Y_IDX];
- dz=B->matrix[Z_IDX]-A->matrix[Z_IDX];
- len=sqrt(dx*dx+dy*dy+dz*dz)*fabs(iy-ix);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(M_PI*(len*len)));
- } else {
- /* Intersection outside of segment or tangental to segment*/
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(0.0));
- }
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::line_sphere_intersect */
- static int TclCmd_vectorxyz_line_sphere_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- MATOBJ *A,*B,*C;
- double brad;
- double ix,iy;
- Tcl_Obj *pResult;
- if(objc<5) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B C brad");
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vectorxyz,&A)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_vectorxyz,&B)) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[3],MATFORM_vectorxyz,&C)) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &brad) ) return TCL_ERROR;
- if(!VectorXYZ_LineSphereIntersect(
- A->matrix[X_IDX],A->matrix[Y_IDX],A->matrix[Z_IDX],
- B->matrix[X_IDX],B->matrix[Y_IDX],B->matrix[Z_IDX],
- C->matrix[X_IDX],C->matrix[Y_IDX],C->matrix[Z_IDX],
- brad,&ix,&iy)) {
- return TCL_OK;
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(ix));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(iy));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::vectorxyz::polygon_normal */
- static int TclCmd_vectorxyz_polygon_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ normal,*element;
- int i,j,n;
- AABBXYZ bbox;
- VectorXYZ_AABB_Reset(bbox);
- VectorXYZ_Zero(normal);
- if(objc<2) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B C ?D...?");
- return TCL_ERROR;
- }
- if(objc==2) {
- Tcl_Obj **elemPtrs;
- int result;
- result = Tcl_ListObjGetElements(interp, objv[1], &n, &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if(n<3) {
- Tcl_AppendResult(interp, "Needs at least points", 0);
- return TCL_ERROR;
- }
- element=(VectorXYZ *)Vector_Alloc(sizeof(VectorXYZ)*n);
- for(i=0;i<n;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,elemPtrs[i],element[i])) goto error;
- }
- } else {
- n=objc-1;
- if(n<3) {
- Tcl_AppendResult(interp, "Needs at least points", 0);
- return TCL_ERROR;
- }
- element=(VectorXYZ *)Vector_Alloc(sizeof(VectorXYZ)*n);
- for(i=1;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],element[i-1])) goto error;
- VectorXYZ_AABB_Measure(element[i-1],bbox);
- }
- }
- if(n==3) {
- VectorXYZ one,two;
- VectorXYZ_Subtract(one, element[1], element[0]);
- VectorXYZ_Subtract(two, element[2], element[0]);
- normal[X_IDX] = one[Y_IDX]*two[Z_IDX] - one[Z_IDX]*two[Y_IDX];
- normal[Y_IDX] = one[Z_IDX]*two[X_IDX] - one[X_IDX]*two[Z_IDX];
- normal[Z_IDX] = one[X_IDX]*two[Y_IDX] - one[Y_IDX]*two[X_IDX];
- } else {
- for(i=0;i<n;i++) {
- j=(i+1)%n;
- normal[X_IDX] += (element[j][Y_IDX]-element[i][Y_IDX]) * (element[j][Z_IDX]+element[i][Z_IDX]);
- normal[Y_IDX] += (element[j][Z_IDX]-element[i][Z_IDX]) * (element[j][X_IDX]+element[i][X_IDX]);
- normal[Z_IDX] += (element[j][X_IDX]-element[i][X_IDX]) * (element[j][Y_IDX]+element[i][Y_IDX]);
- }
- }
- /* symmetrical axis aligned figures will produce a zero normal */
- if(VectorXYZ_IsZero(normal)) {
- if(fabs((bbox[Z_MIN_IDX]-bbox[Z_MAX_IDX])) < Vector_Tolerance) {
- normal[X_IDX]=0.0;
- normal[Y_IDX]=0.0;
- normal[Z_IDX]=1.0;
- } else if (fabs((bbox[Z_MIN_IDX]-bbox[Z_MAX_IDX])) < Vector_Tolerance) {
- normal[X_IDX]=0.0;
- normal[Y_IDX]=1.0;
- normal[Z_IDX]=0.0;
- } else {
- normal[X_IDX]=1.0;
- normal[Y_IDX]=0.0;
- normal[Z_IDX]=0.0;
- }
- } else {
- VectorXYZ_Normalize(normal);
- }
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(normal));
- Odie_Free((char *)element);
- return TCL_OK;
- error:
- Odie_Free((char *)element);
- return TCL_ERROR;
- }
- /* Tcl Proc ::vectorxyz::polygon_center */
- static int TclCmd_vectorxyz_polygon_center(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ center,*element;
- int i,n;
- VectorXYZ_Zero(center);
- if(objc<2) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B C ?D...?");
- return TCL_ERROR;
- }
- if(objc==2) {
- Tcl_Obj **elemPtrs;
- int result;
- result = Tcl_ListObjGetElements(interp, objv[1], &n, &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
- if(n<3) {
- Tcl_AppendResult(interp, "Needs at least points", 0);
- return TCL_ERROR;
- }
- element=(VectorXYZ *)Vector_Alloc(sizeof(VectorXYZ)*n);
- for(i=0;i<n;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,elemPtrs[i],element[i])) goto error;
- }
- } else {
- n=objc-1;
- if(n<3) {
- Tcl_AppendResult(interp, "Needs at least points", 0);
- return TCL_ERROR;
- }
- element=(VectorXYZ *)Vector_Alloc(sizeof(VectorXYZ)*n);
- for(i=1;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],element[i-1])) goto error;
- }
- }
- for(i=0;i<n;i++) {
- center[X_IDX] += element[i][X_IDX];
- center[Y_IDX] += element[i][Y_IDX];
- center[Z_IDX] += element[i][Z_IDX];
- }
- center[X_IDX] /= n;
- center[Y_IDX] /= n;
- center[Z_IDX] /= n;
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(center));
- Odie_Free((char *)element);
- return TCL_OK;
- error:
- Odie_Free((char *)element);
- return TCL_ERROR;
- }
- /* Tcl Proc ::vectorxyz::flatten */
- static int TclCmd_vectorxyz_flatten(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- VectorXYZ point;
- int i,j;
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- if(objc==2) {
- Tcl_Obj **rowPtrs;
- int rows;
- if(Tcl_ListObjGetElements(interp, objv[1], &rows, &rowPtrs)) {
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- for(j=0;j<rows;j++) {
- if(Odie_GetVectorXYZFromTclObj(interp,rowPtrs[j],point)) return TCL_ERROR;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[Y_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[Z_IDX]));
- }
- } else {
- for(i=1;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],point)) return TCL_ERROR;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[Y_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(point[Z_IDX]));
- }
- }
- Tcl_SetObjResult(interp,pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_aabb_xyz */
- static int TclCmd_matrix_to_aabb_xyz(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_aabb_xyz,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_affine */
- static int TclCmd_matrix_to_affine(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_affine,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_bbox_xy */
- static int TclCmd_matrix_to_bbox_xy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_bbox_xy,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_cylindrical */
- static int TclCmd_matrix_to_cylindrical(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_cylindrical,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_euler */
- static int TclCmd_matrix_to_euler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_euler,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_heading */
- static int TclCmd_matrix_to_heading(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_heading,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_mat2 */
- static int TclCmd_matrix_to_mat2(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_mat2,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_mat3 */
- static int TclCmd_matrix_to_mat3(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_mat3,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_mat4 */
- static int TclCmd_matrix_to_mat4(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_mat4,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_null */
- static int TclCmd_matrix_to_null(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_null,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_polar */
- static int TclCmd_matrix_to_polar(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_polar,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_quaternion */
- static int TclCmd_matrix_to_quaternion(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_quaternion,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_scaler */
- static int TclCmd_matrix_to_scaler(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_scaler,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_spherical */
- static int TclCmd_matrix_to_spherical(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_spherical,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_unknown */
- static int TclCmd_matrix_to_unknown(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_unknown,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_vector_xy */
- static int TclCmd_matrix_to_vector_xy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vector_xy,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_vector_xyz */
- static int TclCmd_matrix_to_vector_xyz(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vector_xyz,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::matrix::to_vector_xyzw */
- static int TclCmd_matrix_to_vector_xyzw(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_MatrixObj *A;
- if(objc < 3) {
- Tcl_WrongNumArgs( interp, 1, objv, "A" );
- return TCL_ERROR;
- }
- if(Odie_GetMatrixFromTclObj(interp,objv[1],MATFORM_vector_xyzw,&A)) return TCL_ERROR;
- Tcl_SetObjResult(interp,Matrix_To_TclObj(A));
- return TCL_OK;
- }
- /* Tcl Proc ::tcl::mathfunc::to_fuzzy */
- static int TclCmd_tcl_mathfunc_to_fuzzy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double ax;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&ax)) {
- Tcl_SetObjResult(interp,objv[1]);
- return TCL_OK;
- }
- Tcl_SetObjResult(interp,ODIE_NewFuzzyObj(ax));
- return TCL_OK;
- }
- /* Tcl Proc ::tcl::mathfunc::fuzzy_abs */
- static int TclCmd_tcl_mathfunc_fuzzy_abs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double value;
- if(objc!=2) {
- Tcl_WrongNumArgs(interp, 1, objv, "avalue");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(NULL,objv[1],&value)) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(fabs(value)));
- return TCL_OK;
- }
- /* Tcl Proc ::tcl::mathfunc::fuzzy_compare */
- static int TclCmd_tcl_mathfunc_fuzzy_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int result;
- double epsilon=0.01;
- if(objc!=3 && objc!=4) {
- Tcl_WrongNumArgs(interp, 1, objv, "avalue bvalue ?epsilon?");
- return TCL_ERROR;
- }
- if(objc==4) {
- if(Tcl_GetDoubleFromObj(interp,objv[3],&epsilon)) return TCL_ERROR;
- }
- result=ODIE_Fuzzy_Compare_TclObj(objv[1],objv[2],epsilon);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::tcl::mathfunc::fuzzy_is_zero */
- static int TclCmd_tcl_mathfunc_fuzzy_is_zero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int result;
- double value;
- if(objc!=2) {
- Tcl_WrongNumArgs(interp, 1, objv, "avalue");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(NULL,objv[1],&value)) {
- result=0;
- } else {
- result=ODIE_Real_Is_Zero(value);
- }
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::tcl::mathfunc::fuzzy_gt_zero */
- static int TclCmd_tcl_mathfunc_fuzzy_gt_zero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int result;
- double value;
- if(objc!=2) {
- Tcl_WrongNumArgs(interp, 1, objv, "avalue");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(NULL,objv[1],&value)) {
- result=0;
- } else {
- result=ODIE_Real_Is_Zero(value) ? 1 : 0;
- }
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::tcl::mathfunc::fuzzy_epsilon */
- static int TclCmd_tcl_mathfunc_fuzzy_epsilon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(__FLT_EPSILON__));
- return TCL_OK;
- }
- /* Tcl Proc ::triag_test_rightof */
- static int TclCmd_triag_test_rightof(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- TriagPoint A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &A.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &A.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &B.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &B.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &P.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &P.y) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Odie_LiteralIntObj(rightOf(&A, &B, &P)));
- return TCL_OK;
- }
- /* Tcl Proc ::triag_test_dotprod */
- static int TclCmd_triag_test_dotprod(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- TriagPoint A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &A.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &A.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &B.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &B.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &P.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &P.y) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(Dot_Product(&A, &B, &P)));
- return TCL_OK;
- }
- /* Tcl Proc ::triag_test_angle */
- static int TclCmd_triag_test_angle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- TriagPoint A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &A.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &A.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &B.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &B.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &P.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &P.y) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(angleOf(&A, &B, &P)));
- return TCL_OK;
- }
- /* Tcl Proc ::triag_test_ideal */
- static int TclCmd_triag_test_ideal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- TriagPoint A, B, P;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X0 Y0 X1 Y1 X2 Y2");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &A.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &A.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &B.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &B.y) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &P.x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &P.y) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(idealAngle(&A, &B, &P)));
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::create */
- static int TclCmd_polygon_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- int isnew;
- Odie_Polygon *p;
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- if(isnew) {
- Tcl_SetObjResult(interp, Odie_Polygon_NewTclObj(p));
- } else {
- Tcl_SetObjResult(interp, objv[1]);
- }
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::compare */
- static int TclCmd_polygon_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_Polygon *polyA,*polyB;
- int isNewA,isNewB,result=0;
- int i;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &polyA, &isNewA) ) return TCL_ERROR;
- if( Odie_Polygon_GetFromTclObj(interp, objv[2], &polyB, &isNewB) ) return TCL_ERROR;
- result=Odie_Poly_Compare(polyA,polyB);
- if(isNewA) Odie_Poly_ShimmerOrFree_TclObj(objv[1],polyA);
- if(isNewB) Odie_Poly_ShimmerOrFree_TclObj(objv[2],polyB);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::simplify */
- static int TclCmd_polygon_simplify(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- Odie_Polygon *pPoly,*pNewPoly;
- int i,isnew;
- int colinear;
- double ax,ay,bx,by,cx,cy;
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- pNewPoly=(Odie_Polygon *)Odie_Alloc(sizeof(*pNewPoly)+(pPoly->nVertex+2)*sizeof(pNewPoly->v[0]));
- pNewPoly->nVertex=0;
- ax=pPoly->v[pPoly->nVertex-1][X_IDX];
- ay=pPoly->v[pPoly->nVertex-1][Y_IDX];
- bx=pPoly->v[0][X_IDX];
- by=pPoly->v[0][Y_IDX];
- if(ax==bx && ay==by) {
- ax=pPoly->v[pPoly->nVertex-2][X_IDX];
- ay=pPoly->v[pPoly->nVertex-2][Y_IDX];
- }
- for(i=1;i<pPoly->nVertex;i++) {
- cx=pPoly->v[i][X_IDX];
- cy=pPoly->v[i][Y_IDX];
- colinear=Odie_IsColinear(ax,ay,bx,by,cx,cy);
- if(!colinear) {
- pNewPoly->v[pNewPoly->nVertex][X_IDX]=bx;
- pNewPoly->v[pNewPoly->nVertex][Y_IDX]=by;
- pNewPoly->nVertex++;
- }
- ax=bx;
- ay=by;
- bx=cx;
- by=cy;
- }
- cx=pPoly->v[0][X_IDX];
- cy=pPoly->v[0][Y_IDX];
- colinear=Odie_IsColinear(ax,ay,bx,by,cx,cy);
- if(!Odie_IsColinear(ax,ay,bx,by,cx,cy)) {
- pNewPoly->v[pNewPoly->nVertex][X_IDX]=bx;
- pNewPoly->v[pNewPoly->nVertex][Y_IDX]=by;
- pNewPoly->nVertex++;
- }
- if( pNewPoly->v[pNewPoly->nVertex-1][X_IDX]!=pNewPoly->v[0][X_IDX] || pNewPoly->v[pNewPoly->nVertex-1][Y_IDX]!=pNewPoly->v[0][Y_IDX] ){
- pNewPoly->v[pNewPoly->nVertex][X_IDX] = pNewPoly->v[0][X_IDX];
- pNewPoly->v[pNewPoly->nVertex][Y_IDX] = pNewPoly->v[0][Y_IDX];
- pNewPoly->nVertex++;
- }
- Odie_Polygon_ComputeArea(interp,pNewPoly);
- Tcl_SetObjResult(interp, Odie_Polygon_NewTclObj(pNewPoly));
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::area */
- static int TclCmd_polygon_area(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_Polygon *p;
- int isnew;
- int i;
- double area;
- if( objc<2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N ?N...?");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- area=p->area;
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- for(i=2;i<objc;i++) {
- if( Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- area+=p->area;
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(area));
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::bbox */
- static int TclCmd_polygon_bbox(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly bbox N
- **
- ** Return the bounding box for a polygon
- */
- Odie_Polygon *p;
- int isnew;
- Tcl_Obj *pResult;
- double bbox_x0,bbox_y1,bbox_x1,bbox_y0;
- int i;
- if( objc<2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N ?N...?");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- bbox_x0=p->bbox[BBOX_X0_IDX];
- bbox_x1=p->bbox[BBOX_X1_IDX];
- bbox_y0=p->bbox[BBOX_Y0_IDX];
- bbox_y1=p->bbox[BBOX_Y1_IDX];
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- for(i=2;i<objc;i++) {
- if( Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- if(p->bbox[BBOX_X0_IDX] < bbox_x0) bbox_x0=p->bbox[BBOX_X0_IDX];
- if(p->bbox[BBOX_X1_IDX] > bbox_x1) bbox_x1=p->bbox[BBOX_X1_IDX];
- if(p->bbox[BBOX_Y0_IDX] < bbox_y0) bbox_y0=p->bbox[BBOX_Y0_IDX];
- if(p->bbox[BBOX_Y1_IDX] > bbox_y1) bbox_y1=p->bbox[BBOX_Y1_IDX];
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- }
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(bbox_x0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(bbox_y1));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(bbox_x1));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(bbox_y0));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::info */
- static int TclCmd_polygon_info(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygon
- */
- Tcl_Obj *pResult;
- Odie_Polygon *p;
- int i,isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nVertex-1; i++){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(p->v[i][X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(p->v[i][Y_IDX]));
- }
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::intersect */
- static int TclCmd_polygon_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly intersect N1 N2
- **
- ** Return a list of 3 elements where the first element is the
- ** area of intersection between polygons N1 and N2 and the remaining
- ** 3 elements are the X and Y coordinates of a point within both
- ** polygons.
- **
- ** The current implementation returns an approximation. We might
- ** change it to compute the exact intersection later.
- */
- Odie_Polygon *p1, *p2;
- int isnew1,isnew2;
- double area;
- double xInside = 0.0, yInside = 0.0;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N1 N2");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p1, &isnew1) ) return TCL_ERROR;
- if( Odie_Polygon_GetFromTclObj(interp, objv[2], &p2, &isnew2) ) {
- if(isnew1) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p1);
- return TCL_ERROR;
- }
- if( p1->bbox[BBOX_X1_IDX]<=p2->bbox[BBOX_X0_IDX] || p1->bbox[BBOX_X0_IDX]>=p2->bbox[BBOX_X1_IDX]
- || p1->bbox[BBOX_Y1_IDX]<=p2->bbox[BBOX_Y0_IDX] || p1->bbox[BBOX_Y0_IDX]>=p2->bbox[BBOX_Y1_IDX] ){
- area = 0.0;
- }else if( p1->area==0.0 || p2->area==0.0 ){
- area = 0.0;
- }else{
- double x0, y0, x1, y1, dx, dy, xP, yP, xC, yC;
- int i, j, cnt;
- int score, bestScore;
- static const int n = 50;
- char hit[50][50];
- /* Compute the overlap of the bounding boxes of the two polygons. */
- x0 = p1->bbox[BBOX_X0_IDX] < p2->bbox[BBOX_X0_IDX] ? p2->bbox[BBOX_X0_IDX] : p1->bbox[BBOX_X0_IDX];
- y0 = p1->bbox[BBOX_Y1_IDX] > p2->bbox[BBOX_Y1_IDX] ? p2->bbox[BBOX_Y1_IDX] : p1->bbox[BBOX_Y1_IDX];
- x1 = p1->bbox[BBOX_X1_IDX] > p2->bbox[BBOX_X1_IDX] ? p2->bbox[BBOX_X1_IDX] : p1->bbox[BBOX_X1_IDX];
- y1 = p1->bbox[BBOX_Y0_IDX] < p2->bbox[BBOX_Y0_IDX] ? p2->bbox[BBOX_Y0_IDX] : p1->bbox[BBOX_Y0_IDX];
- /* Divide the intersection of the bounding boxes into a n-by-n grid
- ** and count the number of elements in this grid whose centers fall
- ** within both polygons. This will be our approximation for the
- ** intersection of the polygons themselves.
- */
- dx = (x1-x0)/n;
- dy = (y1-y0)/n;
- cnt = 0;
- xC = yC = 0.0;
- for(i=0; i<n; i++){
- xP = x0 + dx*(i+0.5);
- for(j=0; j<n; j++){
- yP = y0 + dy*(j+0.5);
- if( withinPolygon(p1, xP, yP)>0 && withinPolygon(p2, xP, yP)>0 ){
- cnt++;
- hit[i][j] = 1;
- xC += xP;
- yC += yP;
- }else{
- hit[i][j] = 0;
- }
- }
- }
- /* We need to find a good approximation for the center of the
- ** overlap. Begin by computing the center of mass for the
- ** overlapping region. Then find the point inside the intersection
- ** that is nearest the center of mass.
- */
- if( cnt>0 ){
- area = cnt*(x1-x0)*(y0-y1)/(n*n);
- xC /= cnt;
- yC /= cnt;
- bestScore = -1.0;
- for(i=0; i<n; i++){
- xP = x0 + dx*(i+0.5);
- for(j=0; j<n; j++){
- if( !hit[i][j] ) continue;
- yP = y0 + dy*(j+0.5);
- score = dist(xP,yP,xC,yC);
- if( score<bestScore || bestScore<0.0 ){
- xInside = xP;
- yInside = yP;
- bestScore = score;
- }
- }
- }
- } else {
- area=0.0;
- }
- }
- if(isnew1) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p1);
- if(isnew2) Odie_Poly_ShimmerOrFree_TclObj(objv[2],p2);
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(area));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(xInside));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(yInside));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::within */
- static int TclCmd_polygon_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly within X Y N ?N...?
- **
- ** Return -1, 0, or +1 if the point X,Y is outside, on, or inside
- ** polygon N.
- */
- Odie_Polygon *p;
- int res,isnew;
- double x, y;
- if( objc<4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X Y ?N...?");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &y) ) return TCL_ERROR;
- if(objc==4) {
- if( Odie_Polygon_GetFromTclObj(interp, objv[3], &p, &isnew) ) return TCL_ERROR;
- res = withinPolygon(p, x, y);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[3],p);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
- return TCL_OK;
- } else {
- int i;
- for(i=3;i<objc;i++) {
- if( Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- res = withinPolygon(p, x, y);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- if(res>=0) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- return TCL_OK;
- }
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- }
- /* Tcl Proc ::polygon::center */
- static int TclCmd_polygon_center(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- int isnew;
- Odie_Polygon *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, VectorXY_To_TclObj(p->center));
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::canvascoords */
- static int TclCmd_polygon_canvascoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- Tcl_Obj *pResult;
- int isnew;
- Odie_Polygon *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(interp,pResult, Tcl_NewDoubleObj(p->v[i][X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult, Tcl_NewDoubleObj(p->v[i][Y_IDX]));
- }
- Tcl_SetObjResult(interp, pResult);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::coords */
- static int TclCmd_polygon_coords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- Tcl_Obj *pResult;
- int isnew;
- Odie_Polygon *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(interp,pResult, Tcl_NewDoubleObj(p->v[i][X_IDX]));
- Tcl_ListObjAppendElement(interp,pResult, Tcl_NewDoubleObj(p->v[i][Y_IDX]));
- }
- Tcl_SetObjResult(interp, pResult);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::xycoords */
- static int TclCmd_polygon_xycoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- Tcl_Obj *pResult;
- int isnew;
- Odie_Polygon *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[i]));
- }
- Tcl_SetObjResult(interp, pResult);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::edges */
- static int TclCmd_polygon_edges(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- int isnew;
- int i,j,start,end;
- Odie_Polygon *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- if(objc==2) {
- pResult=Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- j=(i+1)%p->nVertex;
- if(VectorXY_SamePoint(p->v[i],p->v[j])) continue;
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[j]));
- }
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc==3) {
- if(Tcl_GetIntFromObj(interp,objv[2],&start)) goto fail;
- pResult=Tcl_NewObj();
- start=start%p->nVertex;
- end=(start+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[start]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[end]));
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc==4) {
- if(Tcl_GetIntFromObj(interp,objv[2],&start)) goto fail;
- if(Tcl_GetIntFromObj(interp,objv[3],&end)) goto fail;
- pResult=Tcl_NewObj();
- i=start%p->nVertex;
- end=end%p->nVertex;
- while(i!=end) {
- j=(i+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[j]));
- i=(i+1)%p->nVertex;
- }
- j=(i+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXY_To_TclObj(p->v[j]));
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- fail:
- if(pResult) Tcl_DecrRefCount(pResult);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_ERROR;
- }
- /* Tcl Proc ::polygon::bend */
- static int TclCmd_polygon_bend(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int isnew;
- Odie_Polygon *p;
- int i,j,k;
- int total_bend=0;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- for(i=1; i<p->nVertex; i++){
- j=(i+1)%(p->nVertex);
- k=(i+2)%(p->nVertex);
- total_bend+=VectorXY_BendDirection(p->v[i],p->v[j],p->v[k]);
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(total_bend));
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::is_convex */
- static int TclCmd_polygon_is_convex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int isnew;
- Odie_Polygon *p;
- int i,j,k;
- int is_convex=1,total_bend=0;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- for(i=1; i<p->nVertex-1; i++){
- j=(i+1)%(p->nVertex-1);
- k=(i+2)%(p->nVertex-1);
- total_bend+=VectorXY_BendDirection(p->v[i],p->v[j],p->v[k]);
- }
- for(i=1; i<p->nVertex-1; i++){
- int bend;
- j=(i+1)%(p->nVertex-1);
- k=(i+2)%(p->nVertex-1);
- bend=VectorXY_BendDirection(p->v[i],p->v[j],p->v[k]);
- if(bend>0 && total_bend<0) {
- is_convex=0;
- } else if(bend<0 && total_bend>0) {
- is_convex=0;
- }
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(is_convex));
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::segments */
- static int TclCmd_polygon_segments(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult;
- int isnew;
- Odie_Polygon *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_Polygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- int i;
- double px,py;
- pResult=Tcl_NewObj();
- px=p->v[0][X_IDX];
- py=p->v[0][Y_IDX];
- for(i=1; i<p->nVertex-1; i++){
- Tcl_Obj *segment=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(px));
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(py));
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(p->v[i][X_IDX]));
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(p->v[i][Y_IDX]));
- Tcl_ListObjAppendElement(interp,pResult, segment);
- px=p->v[i][X_IDX];
- py=p->v[i][Y_IDX];
- }
- Tcl_Obj *segment=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(px));
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(py));
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(p->v[0][X_IDX]));
- Tcl_ListObjAppendElement(interp,segment, Tcl_NewDoubleObj(p->v[0][Y_IDX]));
- Tcl_ListObjAppendElement(interp,pResult, segment);
- Tcl_SetObjResult(interp, pResult);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::rectangle */
- static int TclCmd_polygon_rectangle(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double cx, cy, radx,rady;
- Tcl_Obj *pResult=Tcl_NewObj();
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- radx=radx/2.0;
- rady=rady/2.0;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::vector_place */
- static int TclCmd_polygon_vector_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double zoom;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double centerx,centery,normalx,normaly,angle;
- if( objc < 8 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery normalx normaly x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&normalx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&normaly)) return TCL_ERROR;
- angle=atan2(normaly,normalx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- for(i=6;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::hexagon */
- static int TclCmd_polygon_hexagon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,flip=0;
- double cx, cy, radx,rady;
- Tcl_Obj *pResult=Tcl_NewObj();
- double coords[7][2]= {
- {1.00, 0.00} , {0.50, M_SQRT3_2} ,
- {-0.50, M_SQRT3_2} , {-1.00, -0.00} ,
- {-0.50, -M_SQRT3_2} , {0.50, -M_SQRT3_2},
- {1.00, 0.00}
- };
- if( objc != 5 && objc != 6){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy ?flip?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- if(objc==6) {
- if(Tcl_GetBooleanFromObj(interp,objv[5],&flip)) return TCL_ERROR;
- }
- radx=radx/2.0;
- rady=rady/2.0;
- for(i=0;i<6;i++) {
- if(flip) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i+1][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i+1][0]));
- } else {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i+1][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i+1][1]));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::poly_place */
- static int TclCmd_polygon_poly_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double zoom;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double centerx,centery,normalx,normaly,angle;
- if( objc < 8 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery normalx normaly x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&normalx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&normaly)) return TCL_ERROR;
- angle=atan2(normaly,normalx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- double startx,starty,prevx,prevy;
- i=6;
- {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- startx=newx;
- starty=newy;
- prevx=newx;
- prevy=newy;
- }
- for(i=8;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevy));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- prevx=newx;
- prevy=newy;
- }
- if(startx != prevx && starty!= prevy) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevy));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(startx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(starty));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::drawobj_orientation */
- static int TclCmd_polygon_drawobj_orientation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *temp;
- int len;
- double nx=100,ny=0;
- if( objc !=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "orientation nxvar nyvar");
- return TCL_ERROR;
- }
- if(Tcl_ListObjLength(interp,objv[1],&len)) return TCL_ERROR;
- if(len>0) {
- if(Tcl_ListObjIndex(interp, objv[1], 0, &temp)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,temp,&nx)) return TCL_ERROR;
- }
- if(len>1) {
- if(Tcl_ListObjIndex(interp, objv[1], 1, &temp)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,temp,&ny)) return TCL_ERROR;
- }
- Tcl_ObjSetVar2(interp,objv[2],NULL,Tcl_NewDoubleObj(nx),0);
- Tcl_ObjSetVar2(interp,objv[3],NULL,Tcl_NewDoubleObj(ny),0);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::corners */
- static int TclCmd_polygon_corners(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double cx, cy, radx,rady;
- if( objc != 5 && objc != 9 ){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy ?x0var y0var x1var y1var?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- if (objc == 5) {
- Tcl_Obj *pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /*
- Replaces
- set x0 [expr {$cx-$d}]
- set y0 [expr {$cy-$d}]
- set x1 [expr {$cx+$d}]
- set y1 [expr {$cy+$d}]
- */
- Tcl_ObjSetVar2(interp,objv[5],NULL,Tcl_NewDoubleObj(cx+radx),0);
- Tcl_ObjSetVar2(interp,objv[6],NULL,Tcl_NewDoubleObj(cy-rady),0);
- Tcl_ObjSetVar2(interp,objv[7],NULL,Tcl_NewDoubleObj(cx-radx),0);
- Tcl_ObjSetVar2(interp,objv[8],NULL,Tcl_NewDoubleObj(cy+rady),0);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::hexgrid_location */
- static int TclCmd_polygon_hexgrid_location(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly hexgrid
- **
- ** Reduce the polygons to a series
- ** of grid coordinates
- */
- Tcl_Obj *pResult,*pX,*pY;
- double gridsize=500.0;
- double x,y;
- int ix,iy;
- int flipped=0;
- if(objc !=4 && objc !=5 && objc !=7 ) {
- Tcl_WrongNumArgs(interp, 1, objv, "GRIDSIZE X Y ?flipped? ?xvar yvar?");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &gridsize) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[2], &ix) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[3], &iy) ) return TCL_ERROR;
- if( objc>4 ) {
- if( Tcl_GetBooleanFromObj(interp, objv[4], &flipped) ) return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- if(flipped) {
- if(iy%2==1) {
- x=(ix+0.5)*gridsize*M_SQRT3_2;
- } else {
- x=ix*gridsize*M_SQRT3_2;
- }
- y=iy*gridsize*0.75;
- } else {
- if(ix%2==1) {
- y=(iy+0.5)*gridsize*M_SQRT3_2;
- } else {
- y=iy*gridsize*M_SQRT3_2;
- }
- x=ix*gridsize*0.75;
- }
- pX=Tcl_NewDoubleObj(x);
- pY=Tcl_NewDoubleObj(y);
- Tcl_ListObjAppendElement(interp, pResult, pX);
- Tcl_ListObjAppendElement(interp, pResult, pY);
- if(objc==7) {
- Tcl_ObjSetVar2(interp,objv[5],NULL,pX,0);
- Tcl_ObjSetVar2(interp,objv[6],NULL,pY,0);
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::hexgrid_create */
- static int TclCmd_polygon_hexgrid_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly hexgrid
- **
- ** Reduce the polygons to a series
- ** of grid coordinates
- */
- Tcl_Obj *pResult;
- Odie_Polygon *p;
- int isnew;
- pResult = Tcl_NewObj();
- double gridsize=500.0;
- double x,y;
- if(objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "GRIDSIZE ?POLY ...?");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &gridsize) ) return TCL_ERROR;
- if( Odie_Polygon_GetFromTclObj(interp, objv[2], &p, &isnew) ) return TCL_ERROR;
- double left=p->bbox[BBOX_X0_IDX];
- double top=p->bbox[BBOX_Y1_IDX];
- double right=p->bbox[BBOX_X1_IDX];
- double bottom=p->bbox[BBOX_Y0_IDX];
- int i;
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[2],p);
- for(i=3;i<objc;i++) {
- if( Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- if(p->bbox[BBOX_X0_IDX] < left) left=p->bbox[BBOX_X0_IDX];
- if(p->bbox[BBOX_Y1_IDX] > top) top=p->bbox[BBOX_Y1_IDX];
- if(p->bbox[BBOX_X1_IDX] > right) right=p->bbox[BBOX_X1_IDX];
- if(p->bbox[BBOX_Y0_IDX] < bottom) bottom=p->bbox[BBOX_Y0_IDX];
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- }
- pResult = Tcl_NewObj();
- left-=gridsize;
- top+=gridsize;
- right+=gridsize;
- bottom-=gridsize;
- int row=0;
- for(y=bottom;y<=top;y+=gridsize) {
- double lstartx=left;
- double gy=floor(y/gridsize)*gridsize;
- row++;
- if(row%2==1) {
- lstartx-=gridsize/2;
- }
- for(x=lstartx;x<=right;x+=gridsize) {
- double gx=floor(x/gridsize)*gridsize;
- int found=0;
- for(i=2;i<objc;i++) {
- int isnew,isWithin;
- Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew);
- isWithin=withinPolygon(p,gx,gy);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- if(isWithin>0) {
- found=1;
- break;
- }
- }
- if(found) {
- Tcl_Obj *coord=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, coord, Tcl_NewDoubleObj(gx));
- Tcl_ListObjAppendElement(interp, coord, Tcl_NewDoubleObj(gy));
- Tcl_ListObjAppendElement(interp, pResult, coord);
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygon::squaregrid_create */
- static int TclCmd_polygon_squaregrid_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly hexgrid
- **
- ** Reduce the polygons to a series
- ** of grid coordinates
- */
- Tcl_Obj *pResult;
- Odie_Polygon *p;
- int isnew;
- pResult = Tcl_NewObj();
- double gridsize=500.0;
- double x,y;
- if(objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "GRIDSIZE ?POLY ...?");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[1], &gridsize) ) return TCL_ERROR;
- if( Odie_Polygon_GetFromTclObj(interp, objv[2], &p, &isnew) ) return TCL_ERROR;
- double left=p->bbox[BBOX_X0_IDX];
- double top=p->bbox[BBOX_Y1_IDX];
- double right=p->bbox[BBOX_X1_IDX];
- double bottom=p->bbox[BBOX_Y0_IDX];
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[2],p);
- int i;
- for(i=3;i<objc;i++) {
- if( Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- if(p->bbox[BBOX_X0_IDX] < left) left=p->bbox[BBOX_X0_IDX];
- if(p->bbox[BBOX_Y1_IDX] > top) top=p->bbox[BBOX_Y1_IDX];
- if(p->bbox[BBOX_X1_IDX] > right) right=p->bbox[BBOX_X1_IDX];
- if(p->bbox[BBOX_Y0_IDX] < bottom) bottom=p->bbox[BBOX_Y0_IDX];
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- }
- pResult = Tcl_NewObj();
- left-=gridsize;
- top+=gridsize;
- right+=gridsize;
- bottom-=gridsize;
- for(y=bottom;y<=top;y+=gridsize) {
- double gy=floor(y/gridsize)*gridsize;
- for(x=left;x<=right;x+=gridsize) {
- double gx=floor(x/gridsize)*gridsize;
- int found=0;
- for(i=2;i<objc;i++) {
- int isnew,isWithin;
- Odie_Polygon_GetFromTclObj(interp, objv[i], &p, &isnew);
- isWithin=withinPolygon(p,gx,gy);
- if(isnew) Odie_Poly_ShimmerOrFree_TclObj(objv[i],p);
- if(isWithin>0) {
- found=1;
- break;
- }
- }
- if(found) {
- Tcl_Obj *coord=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, coord, Tcl_NewDoubleObj(gx));
- Tcl_ListObjAppendElement(interp, coord, Tcl_NewDoubleObj(gy));
- Tcl_ListObjAppendElement(interp, pResult, coord);
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::info */
- static int TclCmd_polygonxyz_info(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew,i,option;
- static const char *POLYGON_fields[] =
- { "id", "area", "bbox", "bend", "center", "is_2d", "is_convex", "normal", "nVertex", "radius", "rotation", "rotation_inv", 0 };
- enum POLYGON_enum { POLYGON_FIELD_ID, POLYGON_FIELD_AREA, POLYGON_FIELD_BBOX, POLYGON_FIELD_BEND, POLYGON_FIELD_CENTER, POLYGON_FIELD_IS_2D, POLYGON_FIELD_IS_CONVEX, POLYGON_FIELD_NORMAL, POLYGON_FIELD_NVERTEX, POLYGON_FIELD_RADIUS, POLYGON_FIELD_ROTATION, POLYGON_FIELD_ROTATION_INV };
- if(objc<2) {
- Tcl_WrongNumArgs(interp, 1, objv, "ID ?field value...?");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- for(i=2;i<objc;i+=2) {
- Tcl_Obj *field,*value;
- int option;
- if((i+1) == objc) break;
- field=objv[i];
- value=objv[i+1];
- if( Tcl_GetIndexFromObj(interp, field, POLYGON_fields, "option", 0, &option) ) return TCL_ERROR;
- switch(option) {
- case POLYGON_FIELD_ID: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing id",NULL);
- return TCL_ERROR;
- }
- pPoly->id=temp;
- break;
- }
- }
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- Tcl_SetObjResult(interp, Odie_FaceXYZ_ToDict(pPoly));
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::create */
- static int TclCmd_polygonxyz_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int isnew=0,i;
- Odie_FaceXYZ *p;
- if( objc<2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "XYZLIST\nor\nXYZ XYZ XYZ XYZ");
- return TCL_ERROR;
- }
- if(objc==2) {
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- if(isnew) {
- Tcl_SetObjResult(interp, Odie_FaceXYZ_NewTclObj(p));
- } else {
- Tcl_SetObjResult(interp, objv[1]);
- }
- } else {
- int nVertex=objc-1;
- p=Odie_FaceXYZ_Create(nVertex);
- for(i=0;i<nVertex;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i+1],p->vertex_xyz[i])) goto createfail;
- }
- if(Odie_FaceXYZ_Compute(interp,p)) goto createfail;
- Tcl_SetObjResult(interp, Odie_FaceXYZ_NewTclObj(p));
- }
- return TCL_OK;
- createfail:
- if(isnew) Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Tcl Proc ::polygonxyz::createxy */
- static int TclCmd_polygonxyz_createxy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int isnew=0;
- Odie_FaceXYZ *p;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N\nor\nX Y X Y X Y...");
- return TCL_ERROR;
- }
- if(objc==2) {
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- if(isnew) {
- Tcl_SetObjResult(interp, Odie_FaceXYZ_NewTclObj(p));
- } else {
- Tcl_SetObjResult(interp, objv[1]);
- }
- } else {
- int i;
- int nVertex=(objc-1)/2;
- if((objc-1)%2!=0) {
- Tcl_AppendResult(interp, "coordinates should come in pairs", 0);
- return TCL_ERROR;
- }
- p=Odie_FaceXYZ_Create(nVertex);
- for(i=0; i<nVertex; i++){
- double d;
- if(Tcl_GetDoubleFromObj(interp, objv[i*2+1], &d)) goto createfail;
- p->vertex_xyz[i][X_IDX] = d;
- if(Tcl_GetDoubleFromObj(interp, objv[i*2+2], &d)) goto createfail;
- p->vertex_xyz[i][Y_IDX] = d;
- p->vertex_xyz[i][Z_IDX] = 0.0;
- }
- if(Odie_FaceXYZ_Compute(interp,p)) goto createfail;
- Tcl_SetObjResult(interp, Odie_FaceXYZ_NewTclObj(p));
- }
- return TCL_OK;
- createfail:
- Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Tcl Proc ::polygonxyz::simplify */
- static int TclCmd_polygonxyz_simplify(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPolygonXYZ,*pNewPolygonXYZ;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPolygonXYZ, &isnew) ) return TCL_ERROR;
- pNewPolygonXYZ=Odie_FaceXYZ_Simplify(pPolygonXYZ);
- Odie_FaceXYZ_Compute(interp,pNewPolygonXYZ);
- Tcl_SetObjResult(interp, Odie_FaceXYZ_NewTclObj(pNewPolygonXYZ));
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPolygonXYZ);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::id */
- static int TclCmd_polygonxyz_id(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 && objc!=3){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- if (objc==3) {
- Tcl_Obj *value=objv[2];
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing id",NULL);
- return TCL_ERROR;
- }
- pPoly->id=temp;
- }
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pPoly->id);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::area */
- static int TclCmd_polygonxyz_area(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *p;
- int isnew;
- int i;
- double area;
- if( objc<2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N ?N...?");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- area=p->area;
- if(isnew) Odie_Free((char *)p);
- for(i=2;i<objc;i++) {
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- area+=p->area;
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[i],p);
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(area));
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::bbox */
- static int TclCmd_polygonxyz_bbox(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- Odie_MatrixObj *C;
- if(pPoly->is_2d) {
- C=Odie_MatrixObj_Create(MATFORM_bbox_xy);
- VectorXY_BBOX_Copy(C->matrix,pPoly->bbox_uv);
- value=Matrix_To_TclObj(C);
- } else {
- C=Odie_MatrixObj_Create(MATFORM_aabb_xyz);
- VectorXYZ_AABB_Copy(C->matrix,pPoly->bbox_xyz);
- value=Matrix_To_TclObj(C);
- }
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::bend */
- static int TclCmd_polygonxyz_bend(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pPoly->bend);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::center */
- static int TclCmd_polygonxyz_center(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pPoly->center);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::is_2d */
- static int TclCmd_polygonxyz_is_2d(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pPoly->is_convex);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::is_convex */
- static int TclCmd_polygonxyz_is_convex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=Tcl_NewBooleanObj(pPoly->is_convex);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::normal */
- static int TclCmd_polygonxyz_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=VectorXYZ_To_TclObj(pPoly->normal);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::nVertex */
- static int TclCmd_polygonxyz_nVertex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=Tcl_NewIntObj(pPoly->nVertex);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::radius */
- static int TclCmd_polygonxyz_radius(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- value=Tcl_NewDoubleObj(pPoly->radius);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::rotation */
- static int TclCmd_polygonxyz_rotation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- Odie_MatrixObj *C;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Copy(C->matrix,pPoly->rotation);
- value=Matrix_To_TclObj(C);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::rotation_inv */
- static int TclCmd_polygonxyz_rotation_inv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPoly;
- int isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPoly, &isnew) ) return TCL_ERROR;
- {
- Tcl_Obj *value;
- Odie_MatrixObj *C;
- C=Odie_MatrixObj_Create(MATFORM_affine);
- Odie_Affine4x4_Copy(C->matrix,pPoly->rotation_inv);
- value=Matrix_To_TclObj(C);
- Tcl_SetObjResult(interp,value);
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPoly);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::axis_of_normal */
- static int TclCmd_polygonxyz_axis_of_normal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *p;
- int axis,isnew;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "axis_of_normal X");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- axis=VectorXYZ_AxisOfNormal(p->normal);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(axis));
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::canvascoords */
- static int TclCmd_polygonxyz_canvascoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygonxyz
- */
- Tcl_Obj *pResult;
- Odie_FaceXYZ *p;
- int i,isnew;
- double xoff=0;
- double yoff=0;
- double xscale=1.0;
- double yscale=-1.0;
- if( objc!=2 && objc != 4 && objc != 6){
- Tcl_WrongNumArgs(interp, 1, objv, "N ?xoff yoff? ?xscale yscale?");
- return TCL_ERROR;
- }
- if(objc>3) {
- if(Tcl_GetDoubleFromObj(interp,objv[2],&xoff)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&yoff)) return TCL_ERROR;
- }
- if(objc==6) {
- if(Tcl_GetDoubleFromObj(interp,objv[4],&xscale)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&yscale)) return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(p->vertex_uv[i][X_IDX]*xscale+xoff));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(p->vertex_uv[i][Y_IDX]*yscale+yoff));
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::coords */
- static int TclCmd_polygonxyz_coords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygonxyz
- */
- Tcl_Obj *pResult;
- Odie_FaceXYZ *p;
- int i,isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(p->vertex_xyz[i]));
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::intcoordsxy */
- static int TclCmd_polygonxyz_intcoordsxy(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygonxyz
- */
- Tcl_DString result;
- Odie_FaceXYZ *p;
- int i,isnew,len;
- char *cResult;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- Tcl_DStringInit(&result);
- for(i=0; i<p->nVertex; i++){
- char out[256];
- sprintf(out,"%d %d",(int)p->vertex_xyz[i][X_IDX],(int)p->vertex_xyz[i][Y_IDX]);
- Tcl_DStringAppendElement(&result,out);
- }
- len=Tcl_DStringLength(&result);
- cResult=Tcl_DStringValue(&result);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(cResult,len));
- Tcl_DStringFree(&result);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::intcoords */
- static int TclCmd_polygonxyz_intcoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygonxyz
- */
- Tcl_DString result;
- Odie_FaceXYZ *p;
- int i,isnew,len;
- char *cResult;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- Tcl_DStringInit(&result);
- for(i=0; i<p->nVertex; i++){
- char out[256];
- sprintf(out,"%d %d %d",(int)p->vertex_xyz[i][X_IDX],(int)p->vertex_xyz[i][Y_IDX],(int)p->vertex_xyz[i][Z_IDX]);
- Tcl_DStringAppendElement(&result,out);
- }
- len=Tcl_DStringLength(&result);
- cResult=Tcl_DStringValue(&result);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(cResult,len));
- Tcl_DStringFree(&result);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::edges */
- static int TclCmd_polygonxyz_edges(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=NULL;
- int isnew;
- Odie_FaceXYZ *p;
- int i,j;
- int start,end;
- if( objc != 2 && objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 1, objv, "N ?start? ?end?");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- if(objc==2) {
- pResult=Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- j=(i+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[j]));
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc==3) {
- if(Tcl_GetIntFromObj(interp,objv[2],&start)) goto fail;
- pResult=Tcl_NewObj();
- start=start%p->nVertex;
- end=(start+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[start]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[end]));
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc==4) {
- if(Tcl_GetIntFromObj(interp,objv[2],&start)) goto fail;
- if(Tcl_GetIntFromObj(interp,objv[3],&end)) goto fail;
- pResult=Tcl_NewObj();
- i=start%p->nVertex;
- end=end%p->nVertex;
- while(i!=end) {
- j=(i+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[j]));
- i=(i+1)%p->nVertex;
- }
- j=(i+1)%p->nVertex;
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[j]));
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[i],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- fail:
- if(pResult) Tcl_DecrRefCount(pResult);
- if(isnew) Odie_Free((char *)p);
- return TCL_ERROR;
- }
- /* Tcl Proc ::polygonxyz::triangles */
- static int TclCmd_polygonxyz_triangles(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=NULL;
- int isnew;
- Odie_FaceXYZ *p;
- int i,j;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N");
- return TCL_ERROR;
- }
- if( Odie_ConvexPolygon_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult=Tcl_NewObj();
- if(p->nVertex==3) {
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[0]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[1]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[2]));
- } else {
- for(i=1; i<p->nVertex; i++){
- j=(i+1)%p->nVertex;
- if(j==0) j=1;
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[0]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[i]));
- Tcl_ListObjAppendElement(interp,pResult, VectorXYZ_To_TclObj(p->vertex_xyz[j]));
- }
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::uvcoords */
- static int TclCmd_polygonxyz_uvcoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygonxyz
- */
- Tcl_Obj *pResult;
- Odie_FaceXYZ *p;
- int i,isnew;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N ");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(0, pResult, VectorXY_To_TclObj(p->vertex_uv[i]));
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::xycoords */
- static int TclCmd_polygonxyz_xycoords(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly info N
- **
- ** Return the coordinates for a polygonxyz
- */
- Tcl_Obj *pResult;
- Odie_FaceXYZ *p;
- int i,isnew,axis,u,v;
- double xoff=0;
- double yoff=0;
- double xscale=1.0;
- double yscale=-1.0;
- if( objc!=2 && objc != 4 && objc != 6){
- Tcl_WrongNumArgs(interp, 1, objv, "N ?xoff yoff? ?xscale yscale?");
- return TCL_ERROR;
- }
- if(objc>3) {
- if(Tcl_GetDoubleFromObj(interp,objv[2],&xoff)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&yoff)) return TCL_ERROR;
- }
- if(objc==6) {
- if(Tcl_GetDoubleFromObj(interp,objv[4],&xscale)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&yscale)) return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- axis=VectorXYZ_AxisOfNormal(p->normal);
- switch(axis) {
- case Z_IDX: u=X_IDX; v=Y_IDX; break;
- case Y_IDX: u=Z_IDX; v=X_IDX; break;
- case X_IDX: u=Y_IDX; v=Z_IDX; break;
- }
- pResult = Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(p->vertex_xyz[i][u]*xscale+xoff));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(p->vertex_xyz[i][v]*yscale+yoff));
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::compare */
- static int TclCmd_polygonxyz_compare(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPolygonXYZA,*pPolygonXYZB;
- int isnewa,isnewb,result=1;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POLY POLY");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPolygonXYZA, &isnewa) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &pPolygonXYZB, &isnewb) ) return TCL_ERROR;
- result=Odie_FaceXYZ_Compare(pPolygonXYZA,pPolygonXYZB);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(result));
- if(isnewa) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPolygonXYZA);
- if(isnewb) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],pPolygonXYZB);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::coplaner */
- static int TclCmd_polygonxyz_coplaner(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *pPolygonXYZA,*pPolygonXYZB;
- int isnewa,isnewb,result=1;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POLY POLY");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &pPolygonXYZA, &isnewa) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &pPolygonXYZB, &isnewb) ) return TCL_ERROR;
- result=Odie_FaceXYZ_Coplaner(pPolygonXYZA,pPolygonXYZB);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(result));
- if(isnewa) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],pPolygonXYZA);
- if(isnewb) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],pPolygonXYZB);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::flipped */
- static int TclCmd_polygonxyz_flipped(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *p,*q;
- int isnewp,isnewq;
- double dp;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POLYGON POLYGON");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnewp) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &q, &isnewq) ) return TCL_ERROR;
- dp = VectorXYZ_Dot_Product(p->normal, q->normal);
- if(dp>=0) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- if(isnewp) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- if(isnewq) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],q);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::side */
- static int TclCmd_polygonxyz_side(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Odie_FaceXYZ *p;
- int isnew;
- VectorXYZ point,vec;
- double dp;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POLYGON POINT");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],point)) return TCL_ERROR;
- VectorXYZ_Subtract(vec, point, p->center);
- dp = VectorXYZ_Dot_Product(vec, p->normal);
- if(dp<=0) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::intersect_test */
- static int TclCmd_polygonxyz_intersect_test(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly intersect N1 N2
- **
- ** Return a list of 3 elements where the first element is the
- ** area of intersection between polygons N1 and N2 and the remaining
- ** 3 elements are the X and Y coordinates of a point within both
- ** polygons.
- **
- ** The current implementation returns an approximation. We might
- ** change it to compute the exact intersection later.
- */
- Odie_FaceXYZ *p1, *p2;
- int isnew1,isnew2,c=0;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N1 N2");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p1, &isnew1) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &p2, &isnew2) ) {
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- return TCL_ERROR;
- }
- if(!Odie_FaceXYZ_Coplaner(p1,p2)) {
- c=0;
- } else if(!AABB_AABB_Intersect(p1->bbox_xyz,p2->bbox_xyz)) {
- c=0;
- }else if( p1->area==0.0 || p2->area==0.0 ){
- c=0;
- }else{
- c = Odie_FaceXYZ_IntersectTest(p1,p2);
- }
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- if(isnew2) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],p2);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::intersect_test_uv */
- static int TclCmd_polygonxyz_intersect_test_uv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly intersect N1 N2
- **
- ** Return a list of 3 elements where the first element is the
- ** area of intersection between polygons N1 and N2 and the remaining
- ** 3 elements are the X and Y coordinates of a point within both
- ** polygons.
- **
- ** The current implementation returns an approximation. We might
- ** change it to compute the exact intersection later.
- */
- Odie_FaceXYZ *p1, *p2;
- int isnew1,isnew2,c=0;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N1 N2");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p1, &isnew1) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &p2, &isnew2) ) {
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- return TCL_ERROR;
- }
- if(!BBOX_BBOX_Intersect(p1->bbox_uv,p2->bbox_uv)) {
- c=0;
- } else if( p1->area==0.0 || p2->area==0.0 ){
- c=0;
- }else{
- c = Odie_FaceXYZ_IntersectTest(p1,p2);
- }
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- if(isnew2) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],p2);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(c));
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::intersect */
- static int TclCmd_polygonxyz_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly intersect N1 N2
- **
- ** Return a list of 3 elements where the first element is the
- ** area of intersection between polygons N1 and N2 and the remaining
- ** 3 elements are the X and Y coordinates of a point within both
- ** polygons.
- **
- ** The current implementation returns an approximation. We might
- ** change it to compute the exact intersection later.
- */
- Odie_FaceXYZ *p1, *p2;
- int isnew1,isnew2;
- double area;
- double xInside = 0.0, yInside = 0.0;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N1 N2");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p1, &isnew1) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &p2, &isnew2) ) {
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- return TCL_ERROR;
- }
- if(!Odie_FaceXYZ_Coplaner(p1,p2)) {
- area=0.0;
- } else if(!AABB_AABB_Intersect(p1->bbox_xyz,p2->bbox_xyz)) {
- area = 0.0;
- }else if( p1->area==0.0 || p2->area==0.0 ){
- area = 0.0;
- }else{
- area = Odie_FaceXYZ_AreaOfIntersection(p1,p2,&xInside,&yInside);
- }
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- if(isnew2) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],p2);
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(area));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(xInside));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(yInside));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::intersect_uv */
- static int TclCmd_polygonxyz_intersect_uv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly intersect N1 N2
- **
- ** Return a list of 3 elements where the first element is the
- ** area of intersection between polygons N1 and N2 and the remaining
- ** 3 elements are the X and Y coordinates of a point within both
- ** polygons.
- **
- ** The current implementation returns an approximation. We might
- ** change it to compute the exact intersection later.
- */
- Odie_FaceXYZ *p1, *p2;
- int isnew1,isnew2;
- double area;
- double xInside = 0.0, yInside = 0.0;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "N1 N2");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p1, &isnew1) ) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &p2, &isnew2) ) {
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- return TCL_ERROR;
- }
- if(!BBOX_BBOX_Intersect(p1->bbox_uv,p2->bbox_uv)) {
- area = 0.0;
- }else if( p1->area==0.0 || p2->area==0.0 ){
- area = 0.0;
- }else{
- area = Odie_FaceXYZ_AreaOfIntersection(p1,p2,&xInside,&yInside);
- }
- if(isnew1) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p1);
- if(isnew2) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],p2);
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(area));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(xInside));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(yInside));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::points_within */
- static int TclCmd_polygonxyz_points_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly within POLY XYZ ?XYZ...?
- **
- ** Return a list of XYZ points from the arguments that are contained within
- ** a convex POLY
- */
- VectorXYZ POINT;
- Odie_FaceXYZ *p;
- int res,isnew,i;
- Tcl_Obj *pResult;
- if( objc<3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POLY ?XYZ...?");
- return TCL_ERROR;
- }
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[1], &p, &isnew) ) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(i=2;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],POINT)) goto error;
- res = Odie_FaceXYZ_Within(p, POINT);
- if(res>=0) {
- Tcl_ListObjAppendElement(interp, pResult, VectorXYZ_To_TclObj(POINT));
- }
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- error:
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[1],p);
- Tcl_DecrRefCount(pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::within */
- static int TclCmd_polygonxyz_within(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly within X Y N
- ** or
- ** poly within POINT N
- **
- ** Return -1, 0, or +1 if the point X,Y is outside, on, or inside
- ** polygonxyz N.
- */
- VectorXYZ POINT;
- Odie_FaceXYZ *p;
- int res,isnew;
- if( objc != 3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POINT POLY\nor\nX Y POLY");
- return TCL_ERROR;
- }
- if(objc==3) {
- if(Odie_GetVectorXYZFromTclObj(interp, objv[1],POINT)) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &p, &isnew) ) return TCL_ERROR;
- res = Odie_FaceXYZ_Within(p, POINT);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],p);
- } else {
- double x,y;
- if(Tcl_GetDoubleFromObj(interp,objv[1],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&y)) return TCL_ERROR;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[3], &p, &isnew) ) return TCL_ERROR;
- POINT[X_IDX]=x;
- POINT[Y_IDX]=y;
- res=PolygonUV_Within(p,x,y);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[3],p);
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
- return TCL_OK;
- }
- /* Tcl Proc ::polygonxyz::within_set */
- static int TclCmd_polygonxyz_within_set(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /* poly within X N ?N...?
- **
- ** polygonxyz N.
- */
- VectorXYZ POINT;
- Odie_FaceXYZ *p;
- int res,isnew;
- if( objc<3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "POINT ?N...?");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],POINT)) return TCL_ERROR;
- if(objc==3) {
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[2], &p, &isnew) ) return TCL_ERROR;
- res = Odie_FaceXYZ_Within(p, POINT);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[2],p);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
- return TCL_OK;
- } else {
- int i;
- for(i=2;i<objc;i++) {
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- res = Odie_FaceXYZ_Within(p, POINT);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[i],p);
- if(res>=0) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res));
- return TCL_OK;
- }
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(-1));
- return TCL_OK;
- }
- }
- /* OO Method SegmentSet segment_info */
- static int OOMethod_SegmentSet_segment_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int id,i;
- Segment *pSeg;
- static const char *SEGMENT_fields[] = { "id", "virtual", "from", "to", "exported", "id_left", "id_right", "ignore", "facefwd", "faceback", 0 };
- enum SEGMENT_enum { SEGMENT_FIELD_ID, SEGMENT_FIELD_VIRTUAL, SEGMENT_FIELD_FROM, SEGMENT_FIELD_TO, SEGMENT_FIELD_EXPORTED, SEGMENT_FIELD_ID_LEFT, SEGMENT_FIELD_ID_RIGHT, SEGMENT_FIELD_IGNORE, SEGMENT_FIELD_FACEFWD, SEGMENT_FIELD_FACEBACK };
- if(objc<3) {
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field value...?");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(interp,objv[2],&id)) return TCL_ERROR;
- pSeg=SegmentSet_FindById(pSet, id);
- if(!pSeg) {
- Tcl_AppendResult(interp, "Segment does not exist",0);
- return TCL_ERROR;
- }
- for(i=3;i<objc;i+=2) {
- Tcl_Obj *field,*value;
- int option;
- if((i+1) == objc) break;
- field=objv[i];
- value=objv[i+1];
- if( Tcl_GetIndexFromObj(interp, field, SEGMENT_fields, "option", 0, &option) ) return TCL_ERROR;
- switch(option) {
- case SEGMENT_FIELD_ID: {
- int temp,h;
- if(Tcl_GetIntFromObj(interp,value,&temp)) return TCL_ERROR;
- if(temp!=pSeg->id && temp>0) {
- if(SegmentSet_FindById(pSet, temp)) {
- Tcl_AppendResult(interp, "Segment ID already exists",0);
- return TCL_ERROR;
- }
- LinkRemove(&pSeg->pHash);
- pSeg->id=temp;
- h = hashInt(pSeg->id);
- LinkInsert(&pSet->hashId[h], &pSeg->pHash);
- }
- break; } case SEGMENT_FIELD_VIRTUAL: {
- int temp;
- if(Tcl_GetBooleanFromObj(interp,value,&temp)) return TCL_ERROR;
- pSeg->isVirtual=temp;
- pSet->modified=1;
- break; } case SEGMENT_FIELD_FROM: { break; } case SEGMENT_FIELD_TO: { break; } case SEGMENT_FIELD_EXPORTED: {
- int temp;
- if(Tcl_GetBooleanFromObj(interp,value,&temp)) return TCL_ERROR;
- pSeg->exported=temp;
- pSet->modified=1;
- break; } case SEGMENT_FIELD_ID_LEFT: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) return TCL_ERROR;
- pSeg->idLC=temp;
- pSet->modified=1;
- break; } case SEGMENT_FIELD_ID_RIGHT: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) return TCL_ERROR;
- pSeg->idRC=temp;
- pSet->modified=1;
- break; } case SEGMENT_FIELD_IGNORE: {
- int temp;
- if(Tcl_GetBooleanFromObj(interp,value,&temp)) return TCL_ERROR;
- pSeg->ignore=temp;
- pSet->modified=1;
- break; } case SEGMENT_FIELD_FACEFWD: { break; } case SEGMENT_FIELD_FACEBACK: { break; } }
- }
- Tcl_SetObjResult(interp, Segment_To_Dict(pSeg));
- return TCL_OK;
- }
- /* OO Method SegmentSet SegmentSet_Init */
- static int OOMethod_SegmentSet_SegmentSet_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet;
- pSet=(SegmentSet *)Odie_Alloc(sizeof(SegmentSet));
- pSet->rXZoom = 100.0;
- pSet->rYZoom = -100.0;
- pSet->grid = Vector_Tolerance*2;
- pSet->grain = pSet->grid*0.5;
- pSet->gridSq = pSet->grid*pSet->grid;
- VectorXY_BBOX_Reset(pSet->bbox_uv);
- VectorXYZ_Copy(pSet->normal,Odie_Up_Direction);
- Odie_Affine_From_Normal(pSet->rotation_inv,pSet->normal);
- Odie_Affine4x4_Inverse(pSet->rotation,pSet->rotation_inv);
- Tcl_ObjectSetMetadata(thisObject, &SegmentSetDataType, (ClientData) pSet);
- return TCL_OK;
- }
- /* OO Method SegmentSet modified */
- static int OOMethod_SegmentSet_modified(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- if (objc==3) {
- int temp;
- /* No matter what, wipe the cache face */
- SegmentSet_ClearFaceEdgeCache(pSet);
- if(Tcl_GetBooleanFromObj(interp,objv[2],&temp)) return TCL_ERROR;
- pSet->modified=temp;
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pSet->modified));
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_count */
- static int OOMethod_SegmentSet_segment_count(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pSet->nSeg));
- return TCL_OK;
- }
- /* OO Method SegmentSet bbox */
- static int OOMethod_SegmentSet_bbox(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSet->bbox_uv[BBOX_X0_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSet->bbox_uv[BBOX_Y1_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSet->bbox_uv[BBOX_X1_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSet->bbox_uv[BBOX_Y0_IDX]));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_reset */
- static int OOMethod_SegmentSet_segment_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- SegmentSetClear(pSet);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_add */
- static int OOMethod_SegmentSet_segment_add(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- VectorXYZ A,B;
- int id=-1;
- int lc,rc,virtual=0;
- Segment *pSeg;
- if( objc!=4 && objc!=5 && objc!=8) {
- Tcl_WrongNumArgs(interp, 2, objv, "A B ?ID? ?LC RC VIRTUAL?");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],B)) return TCL_ERROR;
- VectorXYZ_GridAlign(A,pSet->grid);
- VectorXYZ_GridAlign(B,pSet->grid);
- if(VectorXYZ_SamePoint(A,B)) {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- if(objc>4) {
- if(Tcl_GetIntFromObj(interp, objv[4], &id) ) return TCL_ERROR;
- }
- if(objc==8) {
- if(Tcl_GetIntFromObj(interp, objv[5], &lc) ) {
- Tcl_ResetResult(interp);
- lc=0;
- }
- if(Tcl_GetIntFromObj(interp, objv[6], &rc) ) {
- Tcl_ResetResult(interp);
- rc=0;
- }
- if(Tcl_GetIntFromObj(interp, objv[7], &virtual) ) {
- Tcl_ResetResult(interp);
- virtual=0;
- }
- }
- pSeg=SegmentSet_Insert_XYZ(pSet,id,A,B);
- if(pSeg) {
- int count=1;
- pSeg->isVirtual=virtual;
- pSeg->idLC=lc;
- pSeg->idRC=rc;
- count+=SegmentSet_Cleanup_Coincident(pSet,pSeg);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(count));
- } else {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_add_virtual */
- static int OOMethod_SegmentSet_segment_add_virtual(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int i,j,count=0,type;
- VectorXYZ A,B;
- if( objc<4 ) {
- Tcl_WrongNumArgs(interp, 2, objv, "?type? A B ?C...?");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(interp,objv[2],&type)) {
- Tcl_ResetResult(interp);
- j=3;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- } else {
- j=4;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],A)) return TCL_ERROR;
- }
- VectorXYZ_GridAlign(A,pSet->grid);
- count+=SegmentSet_AddVertex(pSet,A);
- for(i=j;i<objc;i++) {
- Segment *pSeg;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],B)) return TCL_ERROR;
- VectorXYZ_GridAlign(B,pSet->grid);
- count+=SegmentSet_AddVertex(pSet,B);
- if(VectorXYZ_SamePoint(A,B)) continue;
- pSeg=Segment_FindByLocation(pSet,A,B);
- if(!pSeg) {
- pSeg=SegmentSet_Insert_XYZ(pSet,-1,A,B);
- if(pSeg) {
- count++;
- pSeg->isVirtual=1;
- count+=SegmentSet_Cleanup_Coincident(pSet,pSeg);
- }
- }
- VectorXYZ_Copy(A,B);
- }
- Tcl_SetObjResult(interp,Tcl_NewIntObj(count));
- return TCL_OK;
- }
- /* OO Method SegmentSet polygon_add */
- static int OOMethod_SegmentSet_polygon_add(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int i;
- int comptid=1;
- if( objc<3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID POLYGON ?POLYGON...?");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(interp, objv[2], &comptid) ) return TCL_ERROR;
- for(i=3;i<objc;i++) {
- Odie_FaceXYZ *p;
- int isnew;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[i], &p, &isnew) ) return TCL_ERROR;
- if(Segset_Insert_Polygon(pSet,p,comptid)) {
- }
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[i],p);
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet vertex_add */
- static int OOMethod_SegmentSet_vertex_add(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int i;
- VectorXYZ A;
- for(i=2;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],A)) continue;
- SegmentSet_AddVertex(pSet,A);
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_delete */
- static int OOMethod_SegmentSet_segment_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int i;
- VectorXYZ A,B;
- if( objc<4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A B ?C?...");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- for(i=3;i<objc;i++) {
- Segment *found;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],B)) return TCL_ERROR;
- if(VectorXYZ_SamePoint(A,B)) continue;
- found=Segment_FindByLocation(pSet,A,B);
- if(found) SegmentSetRemove(pSet,found);
- VectorXYZ_Copy(A,B);
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet delete */
- static int OOMethod_SegmentSet_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *p = GETSEGMENTSET(thisObject);
- int id;
- Segment *pSeg;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( p->busy ){
- Tcl_AppendResult(interp, "cannot \"delete\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (pSeg = SegmentSet_FindById(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- SegmentSetRemove(p,pSeg);
- return TCL_OK;
- }
- /* OO Method SegmentSet cleanup */
- static int OOMethod_SegmentSet_cleanup(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int count=0;
- count+=SegmentSet_Cleanup(pSet,0);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(count));
- return TCL_OK;
- }
- /* OO Method SegmentSet cleanup_looseend */
- static int OOMethod_SegmentSet_cleanup_looseend(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int count=0;
- count+=SegmentSet_Cleanup(pSet,1);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(count));
- return TCL_OK;
- }
- /* OO Method SegmentSet edge_connection */
- static int OOMethod_SegmentSet_edge_connection(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- VectorXYZ A,RESULT;
- int comptid=0;
- if( objc!=3 && objc!=4){
- Tcl_WrongNumArgs(interp, 2, objv, "A ?comptid?");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(objc==4) {
- if(Tcl_GetIntFromObj(interp,objv[3],&comptid)) return TCL_ERROR;
- }
- if(SegmentSet_Edge_Connection(pSet,A,comptid,RESULT)) {
- Tcl_ResetResult(interp);
- } else {
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(RESULT));
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet check_intersecting */
- static int OOMethod_SegmentSet_check_intersecting(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Link *pLoop,*pNext;
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- Link *qLoop,*qNext;
- Segment *pAB;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- for(qLoop=pSet->pAll; qLoop; qLoop=qNext){
- Tcl_Obj *element;
- int c;
- double mua,mub;
- VectorXYZ I1,I2;
- Segment *pCD;
- pCD = qLoop->pLinkNode;
- qNext = qLoop->pNext;
- /* Evaluate lower to higher */
- if(pCD->id==pAB->id) continue;
- if(!VectorXYZ_BBOX_Overlap_TwoVectors(pAB->from,pAB->to,pCD->from,pCD->to)) continue;
- c=VectorXYZ_LineLineIntersect(pAB->from, pAB->to,pCD->from,pCD->to,I1,I2,&mua,&mub);
- if(c==0) continue;
- if(c<=0) continue;
- if(mua>=1.0 || mua<=0.0) continue;
- if(mub>=1.0 || mub<=0.0) continue;
- element=Tcl_NewObj();
- Odie_DictObjPut(interp,element,"result_type:",Odie_LiteralStringObj("intercept"));
- Odie_DictObjPut(interp,element,"result_code:",Tcl_NewIntObj(c));
- Odie_DictObjPut(interp,element,"segment",Segment_To_Dict(pAB));
- Odie_DictObjPut(interp,element,"segment_other",Segment_To_Dict(pCD));
- Odie_DictObjPut(interp,element,"mua:",Tcl_NewDoubleObj(mua));
- Odie_DictObjPut(interp,element,"mub:",Tcl_NewDoubleObj(mub));
- Odie_DictObjPut(interp,element,"intercept1:",VectorXYZ_To_TclObj(I1));
- Odie_DictObjPut(interp,element,"intercept2:",VectorXYZ_To_TclObj(I2));
- Tcl_ListObjAppendElement(interp,pResult,element);
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet check_coincident */
- static int OOMethod_SegmentSet_check_coincident(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Link *pLoop,*pNext;
- Tcl_Obj *pResult;
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- Link *qLoop,*qNext;
- Segment *pAB;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- for(qLoop=pSet->pAll; qLoop; qLoop=qNext){
- Tcl_Obj *element;
- int c;
- Segment *pCD;
- VectorXYZ ICEPT1,ICEPT2;
- pCD = qLoop->pLinkNode;
- qNext = qLoop->pNext;
- /* Evaluate lower to higher */
- if(pCD->id <= pAB->id) continue;
- c=VectorXYZ_LineLineCoincident(pAB->from,pAB->to,pCD->from,pCD->to,ICEPT1,ICEPT2);
- if(c>0) {
- element=Tcl_NewObj();
- Odie_DictObjPut(interp,element,"result_type:",Odie_LiteralStringObj("coincident"));
- Odie_DictObjPut(interp,element,"result_code:",Tcl_NewIntObj(c));
- Odie_DictObjPut(interp,element,"intercept1:",VectorXYZ_To_TclObj(ICEPT1));
- Odie_DictObjPut(interp,element,"intercept2:",VectorXYZ_To_TclObj(ICEPT2));
- Tcl_ListObjAppendElement(interp,pResult,element);
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_linelineintersect */
- static int OOMethod_SegmentSet_segment_linelineintersect(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- VectorXYZ A,B;
- Link *pLoop,*pNext;
- Segment *pAB;
- Tcl_Obj *pResult;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],B)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- Tcl_Obj *element;
- int c;
- double mua,mub;
- VectorXYZ I1,I2;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if(!VectorXYZ_BBOX_Overlap_TwoVectors(A,B,pAB->from,pAB->to)) continue;
- c=VectorXYZ_LineLineIntersect(A, B, pAB->from, pAB->to,I1,I2,&mua,&mub);
- if(c==0) continue;
- if(c<=0) continue;
- if(mua>=1.0 || mua<=0.0) continue;
- if(mub>=1.0 || mub<=0.0) continue;
- element=Tcl_NewObj();
- Odie_DictObjPut(interp,element,"result_type:",Odie_LiteralStringObj("intercept"));
- Odie_DictObjPut(interp,element,"result_code:",Tcl_NewIntObj(c));
- Odie_DictObjPut(interp,element,"segment",Segment_To_Dict(pAB));
- Odie_DictObjPut(interp,element,"mua:",Tcl_NewDoubleObj(mua));
- Odie_DictObjPut(interp,element,"mub:",Tcl_NewDoubleObj(mub));
- Odie_DictObjPut(interp,element,"intercept1:",VectorXYZ_To_TclObj(I1));
- Odie_DictObjPut(interp,element,"intercept2:",VectorXYZ_To_TclObj(I2));
- Tcl_ListObjAppendElement(interp,pResult,element);
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_coincident */
- static int OOMethod_SegmentSet_segment_coincident(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- VectorXYZ A,B;
- Link *pLoop,*pNext;
- Segment *pAB;
- Tcl_Obj *pResult;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A B");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],B)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- int c;
- VectorXYZ ICEPT1,ICEPT2;
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- c=VectorXYZ_LineLineCoincident(A,B,pAB->from,pAB->to,ICEPT1,ICEPT2);
- if(c>0) {
- Tcl_Obj *element=Tcl_NewObj();
- Odie_DictObjPut(interp,element,"result_type:",Odie_LiteralStringObj("coincident"));
- Odie_DictObjPut(interp,element,"result_code:",Tcl_NewIntObj(c));
- Odie_DictObjPut(interp,element,"segment",Segment_To_Dict(pAB));
- Odie_DictObjPut(interp,element,"intersect1:",VectorXYZ_To_TclObj(ICEPT1));
- Odie_DictObjPut(interp,element,"intersect2:",VectorXYZ_To_TclObj(ICEPT2));
- Tcl_ListObjAppendElement(interp,pResult,element);
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_find */
- static int OOMethod_SegmentSet_segment_find(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int i;
- VectorXYZ A;
- Link *pLoop,*pNext;
- Tcl_Obj *pResult;
- if( objc<3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A ?B?...");
- return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- for(i=2;i<objc;i++) {
- Segment *pAB;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],A)) return TCL_ERROR;
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if( VectorXYZ_SamePoint(pAB->from,A) || VectorXYZ_SamePoint(pAB->to,A) ) {
- Tcl_ListObjAppendElement(0, pResult, Segment_To_Dict(pAB));
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet vertex_delete */
- static int OOMethod_SegmentSet_vertex_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- int i;
- VectorXY A;
- Link *pLoop,*pNext;
- if( objc<3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A ?B?...");
- return TCL_ERROR;
- }
- for(i=2;i<objc;i++) {
- Segment *pAB;
- if(Odie_GetVectorXYFromTclObj(interp,objv[i],A)) return TCL_ERROR;
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- pAB = pLoop->pLinkNode;
- pNext = pLoop->pNext;
- if( VectorXYZ_SamePoint(pAB->from,A) || VectorXYZ_SamePoint(pAB->to,A) ) {
- SegmentSetRemove(pSet, pAB);
- }
- }
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_next */
- static int OOMethod_SegmentSet_segment_next(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- VectorXYZ A,B;
- Segment *pAB,*pBC;
- int pBCBack,pBCBend;
- double pBCAngle;
- Tcl_Obj *pResult;
- int backwards;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A B");
- return TCL_ERROR;
- }
- //if(SegmentSetCheck(interp,pSet)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],B)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- pAB=Segment_FindByLocation(pSet,A,B);
- if(!pAB) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- backwards=VectorXYZ_SamePoint(B,pAB->from);
- SegmentSetNext(pSet, pAB, backwards,&pBC,&pBCBack,&pBCBend,&pBCAngle);
- if(!pBC) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(pBCBack) {
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(pBC->from));
- } else {
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(pBC->to));
- }
- return TCL_OK;
- }
- /* OO Method SegmentSet check_oblique */
- static int OOMethod_SegmentSet_check_oblique(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET check_oblique
- ** title: Return a list of points and comptids that form oblique angles
- */
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- int back;
- Link *pAll;
- static double critical=2.0*M_PI/8.0;
- /*
- ** Fill out the skip fields for counter-clockwise faces
- ** and degenerate edges
- */
- for(pAll=pSet->pAll; pAll; pAll=pAll->pNext){
- Segment *pSeg=pAll->pLinkNode;
- pSeg->ignore=0;
- pSeg->test=0;
- pSeg->isBoundary=0;
- pSeg->not_oblique_fwd=0;
- pSeg->not_oblique_back=0;
- }
- for(back=0;back<2;back++) {
- for(pAll=pSet->pAll; pAll; pAll=pAll->pNext){
- int match=0;
- Segment *pAB,*pBC,*pCD,*pDE,*pEF,*pFG;
- VectorXYZ ICEPT;
- int pBCBack,pBCBend,pCDBack,pCDBend,pDEBack,pDEBend,pEFBack,pEFBend,pFGBack,pFGBend;
- double pBCAngle,pCDAngle,pDEAngle,pEFAngle,pFGAngle;
- VectorXYZ pStart,pBCPoint,pCDPoint,pDEPoint,pEFPoint,pFGPoint;
- pAB=pAll->pLinkNode;
- if(SegmentSetNext(pSet, pAB, back,&pBC,&pBCBack,&pBCBend,&pBCAngle)) continue;
- if(pBC==pAB) {
- continue;
- }
- if(pBCBend<0) continue;
- if(SegmentSetNext(pSet, pBC, pBCBack,&pCD,&pCDBack,&pCDBend,&pCDAngle)) continue;
- if(pCD==pAB) {
- continue;
- }
- if(pCDBend<0) continue;
- if(SegmentSetNext(pSet, pCD, pCDBack,&pDE,&pDEBack,&pDEBend,&pDEAngle)) continue;
- if(pDE==pAB) {
- continue;
- }
- if(pDEBend>=0) {
- if(pDEBack) {
- pDE->not_oblique_back=1;
- } else {
- pDE->not_oblique_fwd=1;
- }
- continue;
- }
- if(pDEBack) {
- if(pDE->not_oblique_back) continue;
- } else {
- if(pDE->not_oblique_fwd) continue;
- }
- /* Don't do bends on small deflections (<10 deg) */
- if(fabs(pDEAngle)<critical) continue;
- if(SegmentSetNext(pSet, pDE, pDEBack,&pEF,&pEFBack,&pEFBend,&pEFAngle)) continue;
- if(SegmentSetNext(pSet, pEF, pEFBack,&pFG,&pFGBack,&pFGBend,&pFGAngle)) continue;
- if(back) {
- VectorXYZ_Copy(pStart,pAB->from);
- } else {
- VectorXYZ_Copy(pStart,pAB->to);
- }
- if(pBCBack) {
- VectorXYZ_Copy(pBCPoint,pBC->from);
- } else {
- VectorXYZ_Copy(pBCPoint,pBC->to);
- }
- if(pCDBack) {
- VectorXYZ_Copy(pCDPoint,pCD->from);
- } else {
- VectorXYZ_Copy(pCDPoint,pCD->to);
- }
- if(pDEBack) {
- VectorXYZ_Copy(pDEPoint,pDE->to);
- } else {
- VectorXYZ_Copy(pDEPoint,pDE->from);
- }
- if(pEFBack) {
- VectorXYZ_Copy(pEFPoint,pEF->from);
- } else {
- VectorXYZ_Copy(pEFPoint,pEF->to);
- }
- if(pFGBack) {
- VectorXYZ_Copy(pFGPoint,pFG->from);
- } else {
- VectorXYZ_Copy(pFGPoint,pFG->to);
- }
- match=0;
- if(pDE->test) continue;
- /*
- pAB->ignore=1;
- pBC->ignore=1;
- pCD->ignore=1;
- pDE->ignore=1;
- pEF->ignore=1;
- pFG->ignore=1;
- */
- /* Win lose or fail, mark this segment so we don't try it again */
- if(pDEBack) {
- pDE->not_oblique_back=1;
- } else {
- pDE->not_oblique_fwd=1;
- }
- if(!SegmentSet_Convex_Connection(pSet,pDE,pDEBack,ICEPT)) {
- pDE->test=1;
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(pDEPoint));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(ICEPT));
- }
- pAB->ignore=0;
- pCD->ignore=0;
- pDE->ignore=0;
- pEF->ignore=0;
- pFG->ignore=0;
- }
- }
- #ifdef ODIE_DEBUG
- fflush(stdout);
- #endif
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet check_looseends */
- static int OOMethod_SegmentSet_check_looseends(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *p = GETSEGMENTSET(thisObject);
- Segment *pSeg;
- Link *pAll, *pList;
- Tcl_Obj *pTrue=ODIE_INT_ONE();
- Tcl_Obj *pFalse=ODIE_INT_ZERO();
- Tcl_Obj *pRes = Tcl_NewObj();
- for(pAll=p->pAll; pAll; pAll=pAll->pNext){
- Tcl_Obj *element,*subelement;
- int nSeg;
- pSeg = pAll->pLinkNode;
- pList = SegmentSet_Segments_AtVertex(p, pSeg->from,&nSeg);
- if( nSeg == 1 ){
- element=Tcl_NewObj();
- Odie_DictObjPut(interp,element,"result_type:",Odie_LiteralStringObj("looseend"));
- Odie_DictObjPut(interp,element,"result_code:",pFalse);
- Odie_DictObjPut(interp,element,"id:",Tcl_NewIntObj(pSeg->id));
- Odie_DictObjPut(interp,element,"location:",VectorXYZ_To_TclObj(pSeg->from));
- Odie_DictObjPut(interp,element,"side:",pFalse);
- subelement=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, subelement, Tcl_NewDoubleObj(pSeg->from[X_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, subelement, Tcl_NewDoubleObj(pSeg->from[Y_IDX]/p->rYZoom));
- Odie_DictObjPut(interp,element,"canvas_xy:",subelement);
- Odie_DictObjPut(interp,element,"segment",Segment_To_Dict(pSeg));
- Tcl_ListObjAppendElement(0, pRes, element);
- }
- pList = SegmentSet_Segments_AtVertex(p, pSeg->to,&nSeg);
- if( nSeg ){
- element=Tcl_NewObj();
- Odie_DictObjPut(interp,element,"result_type:",Odie_LiteralStringObj("looseend"));
- Odie_DictObjPut(interp,element,"result_code:",pTrue);
- Odie_DictObjPut(interp,element,"location:",VectorXYZ_To_TclObj(pSeg->to));
- Odie_DictObjPut(interp,element,"side:",pTrue);
- subelement=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, subelement, Tcl_NewDoubleObj(pSeg->to[X_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, subelement, Tcl_NewDoubleObj(pSeg->to[Y_IDX]/p->rYZoom));
- Odie_DictObjPut(interp,element,"canvas_xy:",subelement);
- Odie_DictObjPut(interp,element,"segment",Segment_To_Dict(pSeg));
- Tcl_ListObjAppendElement(0, pRes, element);
- }
- }
- Tcl_SetObjResult(interp, pRes);
- return TCL_OK;
- }
- /* OO Method SegmentSet fix_looseends */
- static int OOMethod_SegmentSet_fix_looseends(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- Segment *pSeg;
- Link *pAll;
- Tcl_Obj *pRes = Tcl_NewObj();
- for(pAll=pSet->pAll; pAll; pAll=pAll->pNext){
- int nSeg;
- Link *pList;
- pSeg = pAll->pLinkNode;
- pList = SegmentSet_Segments_AtVertex(pSet, pSeg->from,&nSeg);
- if( nSeg <= 1 ){
- VectorXYZ ICEPT;
- int comptid=pSeg->idLC;
- if(!SegmentSet_Edge_Connection(pSet,pSeg->from,comptid,ICEPT)) {
- Tcl_ListObjAppendElement(0, pRes, VectorXYZ_To_TclObj(pSeg->from));
- Tcl_ListObjAppendElement(interp, pRes, VectorXYZ_To_TclObj(ICEPT));
- }
- }
- pList = SegmentSet_Segments_AtVertex(pSet, pSeg->to,&nSeg);
- if( nSeg <= 1 ){
- VectorXYZ ICEPT;
- int comptid=pSeg->idRC;
- if(!SegmentSet_Edge_Connection(pSet,pSeg->to,comptid,ICEPT)) {
- Tcl_ListObjAppendElement(0, pRes, VectorXYZ_To_TclObj(pSeg->to));
- Tcl_ListObjAppendElement(interp, pRes, VectorXYZ_To_TclObj(ICEPT));
- }
- }
- }
- Tcl_SetObjResult(interp, pRes);
- return TCL_OK;
- }
- /* OO Method SegmentSet grid */
- static int OOMethod_SegmentSet_grid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- if(objc!=2 && objc!=3) {
- Tcl_WrongNumArgs(interp, 2, objv, "?NEWVALUE?");
- return TCL_ERROR;
- }
- if(objc==3) {
- double temp;
- Tcl_GetDoubleFromObj(interp,objv[2],&temp);
- pSet->grid=temp;
- pSet->gridSq=temp*temp;
- pSet->grain=temp*0.5;
- }
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(pSet->grid));
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_list */
- static int OOMethod_SegmentSet_segment_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult;
- Link *pLoop,*pNext;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- Segment *pAB;
- pAB = pLoop->pLinkNode;
- pNext=pLoop->pNext;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pAB->id));
- Tcl_ListObjAppendElement(0, pResult, Segment_To_Dict(pAB));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_coords */
- static int OOMethod_SegmentSet_segment_coords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult;
- Link *pLoop,*pNext;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- Segment *pSeg;
- pSeg = pLoop->pLinkNode;
- pNext=pLoop->pNext;
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(pSeg->from));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(pSeg->to));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet segment_uvcoords */
- static int OOMethod_SegmentSet_segment_uvcoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *pSet=GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult;
- Link *pLoop,*pNext;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 2, objv, "");
- return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- for(pLoop=pSet->pAll; pLoop; pLoop=pNext){
- VectorXYZ uvfrom,uvto;
- Segment *pSeg;
- pSeg = pLoop->pLinkNode;
- pNext=pLoop->pNext;
- VectorXYZ_MatrixMultiply(uvfrom,pSeg->from,pSet->rotation);
- VectorXYZ_MatrixMultiply(uvto,pSeg->to,pSet->rotation);
- Tcl_ListObjAppendElement(0, pResult, VectorXY_To_TclObj(uvfrom));
- Tcl_ListObjAppendElement(0, pResult, VectorXY_To_TclObj(uvto));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet selfcheck */
- static int OOMethod_SegmentSet_selfcheck(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- SegmentSet *p = GETSEGMENTSET(thisObject);
- return SegmentSet_SelfCheck(interp, p);
- }
- /* OO Method SegmentSet uv_transform */
- static int OOMethod_SegmentSet_uv_transform(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- VectorXYZ normal,translation;
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- int i,option;
- if( objc<3){
- Tcl_WrongNumArgs(interp, 2, objv, "?normal NORMAL? ?rotation AFFINE4x4? ?translate XYZ?");
- return TCL_ERROR;
- }
- static const char *TRANSFORM_opts[] = { "affine", "normal", "polygon", "translate", 0 };
- enum TRANSFORM_enum { TRANSFORM_AFFINE, TRANSFORM_NORMAL, TRANSFORM_POLYGON, TRANSFORM_TRANSLATE };
- for(i=2;i<objc;i+=2) {
- if( Tcl_GetIndexFromObj(interp, objv[i], TRANSFORM_opts, "option", 0, &option) ) return TCL_ERROR;
- switch(option) {
- case TRANSFORM_AFFINE: {
- Odie_MatrixObj *A;
- if(i>=objc) return TCL_ERROR;
- if(Odie_GetMatrixFromTclObj(interp,objv[i+1],MATFORM_affine,&A)) return TCL_ERROR;
- Odie_Affine4x4_Copy(pSet->rotation,A->matrix);
- Odie_Affine4x4_Inverse(pSet->rotation_inv,pSet->rotation);
- return TCL_OK;
- break;
- }
- case TRANSFORM_NORMAL: {
- if(i>=objc) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i+1],normal)) return TCL_ERROR;
- VectorXYZ_Copy(pSet->normal,normal);
- break;
- }
- case TRANSFORM_POLYGON: {
- Odie_FaceXYZ *p;
- int isnew;
- if( Odie_FaceXYZ_GetFromTclObj(interp, objv[i+1], &p, &isnew) ) return TCL_ERROR;
- VectorXYZ_Copy(pSet->normal,p->normal);
- VectorXYZ_Copy(pSet->center,p->center);
- Odie_Affine4x4_Copy(pSet->rotation,p->rotation);
- Odie_Affine4x4_Copy(pSet->rotation_inv,p->rotation_inv);
- if(isnew) Odie_FaceXYZ_ShimmerOrFree_TclObj(objv[i],p);
- return TCL_OK;
- break;
- }
- case TRANSFORM_TRANSLATE: {
- if(i>=objc) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i+1],translation)) return TCL_ERROR;
- VectorXYZ_Copy(pSet->center,translation);
- break;
- }
- } }
- AFFINE rotation_matrix,translation_matrix;
- Odie_Affine_From_Normal(rotation_matrix,pSet->normal);
- Odie_Affine4x4_Translation(translation_matrix,pSet->center);
- Odie_Affine4x4_Multiply(pSet->rotation_inv,translation_matrix,rotation_matrix);
- Odie_Affine4x4_Inverse(pSet->rotation,pSet->rotation_inv);
- return TCL_OK;
- }
- /* OO Method SegmentSet polygons_xyz */
- static int OOMethod_SegmentSet_polygons_xyz(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET polygon_list
- ** title: Return the set of polygons define by segments
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- int i;
- SegmentSet_BuildFaceEdgeCache(pSet);
- for(i=0;i<(pSet->nSeg*2);i++) {
- FaceBoundary *pStart,*pThis;
- Odie_FaceXYZ *pPolyOut;
- int nVertex=0;
- int j,invalid=0,inside_edge=0,outside_edge=0;
- if(pSet->aBoundary[i].faceid!=pSet->aBoundary[i].id) continue;
- if(pSet->aBoundary[i].facebend<0 && !pSet->aBoundary[i].inside_edge) continue;
- if(pSet->aBoundary[i].nSeg<3) continue;
- pStart=pThis=&pSet->aBoundary[i];
- nVertex=pStart->nSeg;
- pPolyOut=Odie_FaceXYZ_Create(nVertex+1);
- pPolyOut->nVertex=nVertex;
- for(pThis=pStart,j=0;j<nVertex;pThis=pThis->pNext,j++) {
- Segment *pSeg;
- if(!pThis) {
- invalid=1;
- break;
- }
- if(pThis->inside_edge) {
- inside_edge++;
- } else if(pThis->outside_edge) {
- outside_edge++;
- }
- pSeg = pThis->pSeg;
- if( pThis->backwards ){
- VectorXYZ_Copy(pPolyOut->vertex_xyz[j],pSeg->to);
- } else {
- VectorXYZ_Copy(pPolyOut->vertex_xyz[j],pSeg->from);
- }
- }
- /*
- if(outside_edge>0 && !inside_edge) {
- invalid=1;
- }
- */
- if(!invalid && nVertex>2) {
- Odie_FaceXYZ_Compute(interp,pPolyOut);
- Tcl_ListObjAppendElement(interp, pResult, Odie_FaceXYZ_NewTclObj(pPolyOut));
- } else {
- Odie_Free(pPolyOut);
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet polygons */
- static int OOMethod_SegmentSet_polygons(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET polygon_list
- ** title: Return the set of polygons define by segments
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- Odie_Polygon *pPolyPrior=NULL;
- int i;
- SegmentSet_BuildFaceEdgeCache(pSet);
- for(i=0;i<(pSet->nSeg*2);i++) {
- FaceBoundary *pStart,*pThis;
- Odie_Polygon *pPolyOut;
- int nVertex=0;
- int j,invalid=0,inside_edge=0,outside_edge=0;
- if(pSet->aBoundary[i].faceid!=pSet->aBoundary[i].id) continue;
- //if(pSet->aBoundary[i].facebend<0 && !pSet->aBoundary[i].inside_edge) continue;
- if(pSet->aBoundary[i].nSeg<3) continue;
- pStart=pThis=&pSet->aBoundary[i];
- nVertex=pStart->nSeg;
- pPolyOut=Odie_Poly_Create(nVertex+1);
- pPolyOut->nVertex=nVertex;
- for(pThis=pStart,j=0;j<nVertex;pThis=pThis->pNext,j++) {
- Segment *pSeg;
- if(!pThis) {
- invalid=1;
- break;
- }
- if(pThis->inside_edge) {
- inside_edge++;
- } else if(pThis->outside_edge) {
- outside_edge++;
- }
- pSeg = pThis->pSeg;
- if( pThis->backwards ){
- VectorXY_Copy(pPolyOut->v[j],pSeg->from);
- } else {
- VectorXY_Copy(pPolyOut->v[j],pSeg->to);
- }
- }
- if(pPolyPrior && Odie_Poly_Compare(pPolyPrior,pPolyOut)==1) {
- invalid=1;
- }
- if(!invalid && nVertex>2) {
- pPolyPrior=pPolyOut;
- Odie_Polygon_ComputeArea(interp,pPolyOut);
- Tcl_ListObjAppendElement(interp, pResult, Odie_Polygon_NewTclObj(pPolyOut));
- } else {
- Odie_Free(pPolyOut);
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet polygon_faces */
- static int OOMethod_SegmentSet_polygon_faces(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET polygon_faces
- ** title: Return the set of polygons defined by segments
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- Odie_Polygon *pPolyPrior=NULL;
- int i;
- SegmentSet_BuildFaceEdgeCache(pSet);
- for(i=0;i<(pSet->nSeg*2);i++) {
- FaceBoundary *pStart,*pThis;
- Odie_Polygon *pPolyOut;
- int nVertex=0;
- int j,invalid=0,inside_edge=0,outside_edge=0;
- if(pSet->aBoundary[i].faceid!=pSet->aBoundary[i].id) continue;
- //if(pSet->aBoundary[i].facebend<0 && !pSet->aBoundary[i].inside_edge) continue;
- if(pSet->aBoundary[i].nSeg<3) continue;
- pStart=pThis=&pSet->aBoundary[i];
- nVertex=pStart->nSeg;
- pPolyOut=Odie_Poly_Create(nVertex+1);
- pPolyOut->nVertex=nVertex;
- for(pThis=pStart,j=0;j<nVertex;pThis=pThis->pNext,j++) {
- Segment *pSeg;
- if(!pThis) {
- invalid=1;
- break;
- }
- if(pThis->inside_edge) {
- inside_edge++;
- } else if(pThis->outside_edge) {
- outside_edge++;
- }
- pSeg = pThis->pSeg;
- if( pThis->backwards ){
- VectorXY_Copy(pPolyOut->v[j],pSeg->from);
- } else {
- VectorXY_Copy(pPolyOut->v[j],pSeg->to);
- }
- }
- if(pPolyPrior && Odie_Poly_Compare(pPolyPrior,pPolyOut)==1) {
- invalid=1;
- }
- if(!invalid && nVertex>2) {
- pPolyPrior=pPolyOut;
- Odie_Polygon_ComputeArea(interp,pPolyOut);
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(i));
- Tcl_ListObjAppendElement(interp, pResult, Odie_Polygon_NewTclObj(pPolyOut));
- } else {
- Odie_Free(pPolyOut);
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SegmentSet polygon_info */
- static int OOMethod_SegmentSet_polygon_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET polygon_list
- ** title: Return the set of polygons define by segments
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- SegmentSet *pSet = GETSEGMENTSET(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- int i;
- SegmentSet_BuildFaceEdgeCache(pSet);
- for(i=0;i<(pSet->nSeg*2);i++) {
- FaceBoundary *pStart,*pThis;
- int j;
- Tcl_Obj *element=Tcl_NewObj();
- Tcl_Obj *coords=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(i));
- Odie_DictObjPut(interp,element,"isloop",Tcl_NewIntObj(pSet->aBoundary[i].isloop));
- Odie_DictObjPut(interp,element,"facebend",Tcl_NewIntObj(pSet->aBoundary[i].facebend));
- Odie_DictObjPut(interp,element,"faceid",Tcl_NewIntObj(pSet->aBoundary[i].faceid));
- Odie_DictObjPut(interp,element,"nSeg",Tcl_NewIntObj(pSet->aBoundary[i].nSeg));
- Odie_DictObjPut(interp,element,"bend",Tcl_NewIntObj(pSet->aBoundary[i].bend));
- Odie_DictObjPut(interp,element,"segid",Tcl_NewIntObj(pSet->aBoundary[i].pSeg->id));
- Odie_DictObjPut(interp,element,"backwards",Tcl_NewIntObj(pSet->aBoundary[i].backwards));
- if(pSet->aBoundary[i].backwards) {
- Tcl_ListObjAppendElement(interp, coords, VectorXYZ_To_TclObj(pSet->aBoundary[i].pSeg->to));
- Tcl_ListObjAppendElement(interp, coords, VectorXYZ_To_TclObj(pSet->aBoundary[i].pSeg->from));
- } else {
- Tcl_ListObjAppendElement(interp, coords, VectorXYZ_To_TclObj(pSet->aBoundary[i].pSeg->from));
- Tcl_ListObjAppendElement(interp, coords, VectorXYZ_To_TclObj(pSet->aBoundary[i].pSeg->to));
- }
- Odie_DictObjPut(interp,element,"coords",coords);
- Tcl_ListObjAppendElement(interp, pResult,element);
- pStart=pThis=&pSet->aBoundary[i];
- if(pStart->id==pStart->faceid) {
- Tcl_Obj *coords=Tcl_NewObj();
- for(j=0;j<pSet->aBoundary[i].nSeg && pThis;j++,pThis=pThis->pNext) {
- Tcl_ListObjAppendElement(interp,coords,Tcl_NewIntObj(pThis->id));
- }
- Odie_DictObjPut(interp,element,"next",coords);
- } else {
- if(pSet->aBoundary[i].pNext) {
- Odie_DictObjPut(interp,element,"next",Tcl_NewIntObj(pSet->aBoundary[i].pNext->id));
- } else {
- Odie_DictObjPut(interp,element,"next",Tcl_NewObj());
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Loader for SegmentSet */
- static int SegmentSet_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::segset" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::segset" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::segset", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- nameObj=Tcl_NewStringObj("segment_info",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_info, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("SegmentSet_Init",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_SegmentSet_Init, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("modified",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_modified, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_count",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_count, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("bbox",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_bbox, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_reset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_reset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_add",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_add, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_add_virtual",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_add_virtual, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("polygon_add",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_polygon_add, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_add",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_vertex_add, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("cleanup",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_cleanup, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete_overlapping",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_cleanup, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("cleanup_looseend",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_cleanup_looseend, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete_overlapping",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_cleanup_looseend, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("edge_connection",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_edge_connection, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("check_intersecting",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_check_intersecting, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("check_coincident",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_check_coincident, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_linelineintersect",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_linelineintersect, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_coincident",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_coincident, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_find",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_find, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_vertex_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_next",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_next, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("check_oblique",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_check_oblique, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("check_looseends",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_check_looseends, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("fix_looseends",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_fix_looseends, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("grid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_grid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_coords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_coords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("segment_uvcoords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_segment_uvcoords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("selfcheck",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_selfcheck, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("uv_transform",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_uv_transform, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("polygons_xyz",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_polygons_xyz, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("polygons",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_polygons, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("polygon_faces",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_polygon_faces, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("polygon_info",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SegmentSet_polygon_info, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::corners */
- static int TclCmd_shapes_corners(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double cx, cy, radx,rady;
- if( objc != 5 && objc != 9 ){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy ?x0var y0var x1var y1var?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- if (objc == 5) {
- Tcl_Obj *pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /*
- Replaces
- set x0 [expr {$cx-$d}]
- set y0 [expr {$cy-$d}]
- set x1 [expr {$cx+$d}]
- set y1 [expr {$cy+$d}]
- */
- Tcl_ObjSetVar2(interp,objv[5],NULL,Tcl_NewDoubleObj(cx+radx),0);
- Tcl_ObjSetVar2(interp,objv[6],NULL,Tcl_NewDoubleObj(cy-rady),0);
- Tcl_ObjSetVar2(interp,objv[7],NULL,Tcl_NewDoubleObj(cx-radx),0);
- Tcl_ObjSetVar2(interp,objv[8],NULL,Tcl_NewDoubleObj(cy+rady),0);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::drawobj_orientation */
- static int TclCmd_shapes_drawobj_orientation(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *temp;
- int len;
- double nx=100,ny=0;
- if( objc !=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "orientation nxvar nyvar");
- return TCL_ERROR;
- }
- if(Tcl_ListObjLength(interp,objv[1],&len)) return TCL_ERROR;
- if(len>0) {
- if(Tcl_ListObjIndex(interp, objv[1], 0, &temp)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,temp,&nx)) return TCL_ERROR;
- }
- if(len>1) {
- if(Tcl_ListObjIndex(interp, objv[1], 1, &temp)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,temp,&ny)) return TCL_ERROR;
- }
- Tcl_ObjSetVar2(interp,objv[2],NULL,Tcl_NewDoubleObj(nx),0);
- Tcl_ObjSetVar2(interp,objv[3],NULL,Tcl_NewDoubleObj(ny),0);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::poly_hex */
- static int TclCmd_shapes_poly_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,flip=0;
- double cx, cy, radx,rady;
- Tcl_Obj *pResult=Tcl_NewObj();
- double coords[7][2]= {
- {1.00, 0.00} , {0.50, M_SQRT3_2} ,
- {-0.50, M_SQRT3_2} , {-1.00, -0.00} ,
- {-0.50, -M_SQRT3_2} , {0.50, -M_SQRT3_2},
- {1.00, 0.00}
- };
- if( objc != 5 && objc != 6){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy ?flip?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- if(objc==6) {
- if(Tcl_GetBooleanFromObj(interp,objv[5],&flip)) return TCL_ERROR;
- }
- radx=radx/2.0;
- rady=rady/2.0;
- for(i=0;i<6;i++) {
- if(flip) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i+1][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i+1][0]));
- } else {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i+1][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i+1][1]));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::poly_place */
- static int TclCmd_shapes_poly_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double zoom;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double centerx,centery,normalx,normaly,angle;
- if( objc < 8 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery normalx normaly x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&normalx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&normaly)) return TCL_ERROR;
- angle=atan2(normaly,normalx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- double startx,starty,prevx,prevy;
- i=6;
- {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- startx=newx;
- starty=newy;
- prevx=newx;
- prevy=newy;
- }
- for(i=8;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevy));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- prevx=newx;
- prevy=newy;
- }
- if(startx != prevx && starty!= prevy) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(prevy));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(startx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(starty));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::polygon_to_vectors */
- static int TclCmd_shapes_polygon_to_vectors(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double px,py,fx,fy;
- if(objc<6 || (objc-1)%2!=0) {
- Tcl_AppendResult(interp, "arguments should contain at least 6 and "
- " a multiple of 2 values", 0);
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&px)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&py)) return TCL_ERROR;
- fx=px;
- fy=py;
- for(i=3;i<objc;i+=2) {
- double x,y;
- if(i+1>objc) break;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(px));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(py));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(x));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(y));
- px=x;
- py=y;
- }
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(px));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(py));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(fx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(fy));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::rectangle_as_polygon */
- static int TclCmd_shapes_rectangle_as_polygon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double cx, cy, radx,rady;
- Tcl_Obj *pResult=Tcl_NewObj();
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- radx=radx/2.0;
- rady=rady/2.0;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::rectangle_as_vectors */
- static int TclCmd_shapes_rectangle_as_vectors(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double cx, cy, radx,rady;
- Tcl_Obj *pResult=Tcl_NewObj();
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- radx=radx/2.0;
- rady=rady/2.0;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx-radx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy-rady));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::vector_place */
- static int TclCmd_shapes_vector_place(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double zoom;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double centerx,centery,normalx,normaly,angle;
- if( objc < 8 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery normalx normaly x1 y1 ?x2 y2?...");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&normalx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[5],&normaly)) return TCL_ERROR;
- angle=atan2(normaly,normalx);
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- for(i=6;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::hexagon */
- static int TclCmd_shapes_hexagon(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i,flip=0;
- double cx, cy, radx,rady;
- Tcl_Obj *pResult=Tcl_NewObj();
- double coords[7][2]= {
- {1.00, 0.00} , {0.50, M_SQRT3_2} ,
- {-0.50, M_SQRT3_2} , {-1.00, -0.00} ,
- {-0.50, -M_SQRT3_2} , {0.50, -M_SQRT3_2},
- {1.00, 0.00}
- };
- if( objc != 5 && objc != 6){
- Tcl_WrongNumArgs(interp, 1, objv, "cx cy dimx dimy ?flip?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&cx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&cy)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&radx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&rady)) return TCL_ERROR;
- if(objc==6) {
- if(Tcl_GetBooleanFromObj(interp,objv[5],&flip)) return TCL_ERROR;
- }
- radx=radx/2.0;
- rady=rady/2.0;
- for(i=0;i<6;i++) {
- if(flip) {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i+1][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i+1][0]));
- } else {
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i][1]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cx+radx*coords[i+1][0]));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(cy+rady*coords[i+1][1]));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::shapes::canvas */
- static int TclCmd_shapes_canvas(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** Apply Matrices
- */
- Tcl_Obj *pResult=Tcl_NewObj();
- int i;
- double zoom;
- double matA[6] = {1.0,0.0,0.0,1.0,0.0,0.0};
- double centerx,centery,width,height,angle=0.0;
- if( objc < 6 || objc>7 ){
- Tcl_WrongNumArgs(interp, 1, objv, "zoom centerx centery ?angle?");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&zoom)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],¢erx)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],¢ery)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&width)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&height)) return TCL_ERROR;
- if(objc==7) {
- if(Tcl_GetDoubleFromObj(interp,objv[4],&angle)) return TCL_ERROR;
- }
- matA[0]=cos(angle);
- matA[1]=sin(angle);
- matA[2]=-sin(angle);
- matA[3]=cos(angle);
- matA[4]=0.0;
- matA[5]=0.0;
- for(i=6;i<objc;i+=2) {
- double x,y,sx,sy,newx,newy;
- if(Tcl_GetDoubleFromObj(interp,objv[i],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[i+1],&y)) return TCL_ERROR;
- sx=(x/zoom);
- sy=(y/zoom);
- newx=matA[0]*sx+matA[1]*sy+matA[4]+centerx;
- newy=matA[2]*sx+matA[3]*sy+matA[5]+centery;
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newx));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(newy));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Plotter actualcoords */
- static int OOMethod_Plotter_actualcoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: PLOTTER actualcoords CANVAS-COORD-LIST
- ** title: Convert from canvas to actual coordinate space
- */
- Plotter *p = GETPLOTTER(thisObject);
- int i, n;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "CANVAS-COORD-LIST");
- return TCL_ERROR;
- }
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- if( n%2!=0 ){
- Tcl_AppendResult(interp, "coordinate list must contain a multiple "
- "of 2 values", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- for(i=0; i<n-1; i+=2){
- double cx, cy;
- Tcl_Obj *pObj;
- VectorXY M;
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &cx) ) break;
- Tcl_ListObjIndex(0, objv[2], i+1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &cy) ) break;
- /* Original Formula
- ** ax = cx*p->rZoom - pS->rXShift;
- ** ay = pS->mxY + (pS->mnY-pS->mxY)*(cy-pS->top)/(pS->btm-pS->top);
- */
- M[X_IDX]=Plotter_xCanvasToActual(p,cx);
- M[Y_IDX]=Plotter_yCanvasToActual(p,cy);
- Tcl_ListObjAppendElement(interp, pResult, VectorXY_To_TclObj(M));
- }
- if( i<n-1 ){
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Plotter canvascoords */
- static int OOMethod_Plotter_canvascoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: PLOTTER canvascoords VECTOR-LIST ?xvar? ?yvar?
- ** title: Convert from actual (a list of vectors) to canvas coordinate space
- **
- */
- Plotter *p = GETPLOTTER(thisObject);
- int i,n,m;
- Tcl_Obj *pResult=NULL;
- double cx, cy, ax, ay;
- Tcl_Obj *pObj;
- int error=0;
- int singlearg=0;
- if( objc!=3 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "VECTOR-LIST ?xvar yvar?");
- return TCL_ERROR;
- }
- if(objv[2]->typePtr==&matrix_tclobjtype) {
- singlearg=1;
- } else {
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- Tcl_ListObjIndex(0, objv[2], 0, &pObj);
- if( Tcl_ListObjLength(interp, pObj, &m) ) return TCL_ERROR;
- if(m==1) {
- singlearg=1;
- }
- }
- if(singlearg) {
- /*
- ** Accept a single vector as an argument
- ** Do this to ensure we don't interpret the
- ** value as a list
- */
- MATOBJ *M;
- if(Odie_GetMatrixFromTclObj(interp,objv[2],MATFORM_vectorxy,&M)) return TCL_ERROR;
- if(!M) return TCL_ERROR;
- ax=*(M->matrix+X_IDX);
- ay=*(M->matrix+Y_IDX);
- cx = Plotter_xActualToCanvas(p,ax);
- cy = Plotter_yActualToCanvas(p,ay);
- if(objc==5) {
- Tcl_ObjSetVar2(interp,objv[3],NULL,Tcl_NewDoubleObj(cx),0);
- Tcl_ObjSetVar2(interp,objv[4],NULL,Tcl_NewDoubleObj(cy),0);
- }
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(cx));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(cy));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc != 5) {
- pResult = Tcl_NewObj();
- }
- for(i=0; i<n; i++){
- MATOBJ *M;
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if(Odie_GetMatrixFromTclObj(interp,pObj,MATFORM_vectorxy,&M)) return TCL_ERROR;
- ax=*(M->matrix+X_IDX);
- ay=*(M->matrix+Y_IDX);
- cx = Plotter_xActualToCanvas(p,ax);
- cy = Plotter_yActualToCanvas(p,ay);
- if(objc==5) {
- Tcl_ObjSetVar2(interp,objv[3],NULL,Tcl_NewDoubleObj(cx),0);
- Tcl_ObjSetVar2(interp,objv[4],NULL,Tcl_NewDoubleObj(cy),0);
- return TCL_OK;
- } else {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(cx));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(cy));
- }
- }
- if(error) {
- if(pResult) {
- Tcl_DecrRefCount(pResult);
- }
- return TCL_ERROR;
- }
- if( i<n-3 ){
- Tcl_AppendResult(interp, "Did not reach the end", 0);
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Plotter centerset */
- static int OOMethod_Plotter_centerset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: PLOTTER centerset zoom width height
- ** title: Set all settings for plotter in one go
- ** description: Sets the center of the screen based on the width
- ** and height (0,0 = width/2 height/2)
- */
- Plotter *p = GETPLOTTER(thisObject);
- double rZoom,rXOffset,rYOffset;
- if(objc!=5) {
- printf("%d\n",objc);
- Tcl_WrongNumArgs(interp, 2, objv, "ZOOM XOFFSET YOFFSET");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &rZoom) ) return TCL_ERROR;
- p->rZoom = rZoom;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &rXOffset) ) return TCL_ERROR;
- p->rXOffset = -rXOffset/2.0;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &rYOffset) ) return TCL_ERROR;
- p->rYOffset = -rYOffset/2.0;
- return TCL_OK;
- }
- /* OO Method Plotter xoffset */
- static int OOMethod_Plotter_xoffset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: PLOTTER xoffset ?AMT?
- ** title: Change the X-Offset
- */
- Plotter *p = GETPLOTTER(thisObject);
- double rXOffset;
- if( objc!=2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?ZOOM?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- if( Tcl_GetDoubleFromObj(interp, objv[2], &rXOffset) ) return TCL_ERROR;
- p->rXOffset = rXOffset;
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(p->rXOffset));
- return TCL_OK;
- }
- /* OO Method Plotter yoffset */
- static int OOMethod_Plotter_yoffset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: PLOTTER yoffset ?AMT?
- ** title: Change the Y-Offset
- */
- Plotter *p = GETPLOTTER(thisObject);
- double rYOffset;
- if( objc!=2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?ZOOM?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- if( Tcl_GetDoubleFromObj(interp, objv[2], &rYOffset) ) return TCL_ERROR;
- p->rYOffset = rYOffset;
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(p->rYOffset));
- return TCL_OK;
- }
- /* OO Method Plotter zoom */
- static int OOMethod_Plotter_zoom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: PLOTTER zoom ?ZOOM?
- ** title: Query or change the zoom factor.
- */
- Plotter *p = GETPLOTTER(thisObject);
- Tcl_Obj *pResult;
- if( objc!=2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?ZOOM?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- double r;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &r) ) return TCL_ERROR;
- p->rZoom = r;
- }
- pResult = Tcl_NewDoubleObj(p->rZoom);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Plotter constructor */
- static int OOMethod_Plotter_constructor(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Plotter *p;
- p = (Plotter *)Odie_Alloc( sizeof(*p) );
- p->rZoom = 1.0;
- p->rXOffset = 0.0;
- p->rYOffset = 0.0;
- Tcl_ObjectSetMetadata(thisObject, &PlotterDataType, (ClientData) p);
- return TCL_OK;
- }
- /* Loader for Plotter */
- static int Plotter_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::plotter" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::plotter" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::plotter", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- /* Attach the constructor to the class */
- Tcl_ClassSetConstructor(interp, curClass, Tcl_NewMethod(interp, curClass, NULL, 1, &OOMethodType_Plotter_constructor, NULL));
- nameObj=Tcl_NewStringObj("actualcoords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Plotter_actualcoords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("canvascoords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Plotter_canvascoords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("centerset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Plotter_centerset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("xoffset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Plotter_xoffset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("yoffset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Plotter_yoffset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("zoom",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Plotter_zoom, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* OO Method Slicer drawline */
- static int OOMethod_Slicer_drawline(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER drawline_dxyz CANVAS PATH TAG TRANSDECK-TAG P-TAG
- ** title: Return TK to draw a line on a canvas
- */
- Slicer *p = GETSLICER(thisObject);
- int i, j=0, totalN, n, len;
- double *xCoord,*yCoord; /* Actual coordinates of line to draw */
- int *deckCoord;
- struct OneSlice **apDeck; /* Array of all decks */
- const char *zKTag=NULL;
- const char *zXTag=NULL;
- const char *zBTag=NULL;
- if( objc < 5 && objc > 7 ){
- Tcl_WrongNumArgs(interp, 2, objv,
- "CANVAS PATH TAG ?TRANSDECK-TAG? ?BEND-TAG?");
- return TCL_ERROR;
- }
- if( Tcl_ListObjLength(interp, objv[3], &n) ) return TCL_ERROR;
- totalN=n+2;
- xCoord = (double *)Odie_Alloc(sizeof(xCoord[0])*totalN);
- yCoord = (double *)Odie_Alloc(sizeof(yCoord[0])*totalN);
- deckCoord = (int *)Odie_Alloc(sizeof(deckCoord[0])*(totalN));
- apDeck = (struct OneSlice **)Odie_Alloc(sizeof(apDeck[0])*(totalN));
- if( xCoord==0 || yCoord == 0 || deckCoord == 0 || apDeck == 0 ) {
- return TCL_ERROR;
- }
- j=0;
- for(i=0; i<n; i++){
- Tcl_Obj *deckObj,*xObj,*yObj;
- Tcl_ListObjIndex(0, objv[3], i, &deckObj);
- if( Tcl_GetIntFromObj(interp, deckObj, &deckCoord[j]) || i>(n-4) ) {
- if(Location_FromTclObj(interp,deckObj,&deckCoord[j],&xCoord[j],&yCoord[j])) {
- goto badRoute;
- }
- } else {
- if(i++ >= n) goto badRoute;
- Tcl_ListObjIndex(0, objv[3], i, &xObj);
- if(i++ >= n) goto badRoute;
- Tcl_ListObjIndex(0, objv[3], i, &yObj);
- i++;
- if( Odie_GetMatrixElementFromObj(interp, xObj, xCoord, j) ) goto badRoute;
- if( Odie_GetMatrixElementFromObj(interp, yObj, yCoord, j) ) goto badRoute;
- }
- if(deckCoord[j]==deckCoord[j-1]) {
- apDeck[j]=apDeck[j-1];
- } else {
- apDeck[j]=Slicer_getDeck_FromInt(p,deckCoord[j]); if(!apDeck[j]) goto badRoute;
- }
- j++;
- }
- zKTag = (const char *)Tcl_GetStringFromObj(objv[4], &len);
- if(objc>=6) {
- zXTag=(const char *)Tcl_GetStringFromObj(objv[5], &len);
- if(len==0) {
- zXTag=NULL;
- }
- }
- if(objc==7) {
- zBTag=(const char *)Tcl_GetStringFromObj(objv[6], &len);
- if(len==0) {
- zBTag=NULL;
- }
- }
- slicer_drawline_do(interp,p,j,deckCoord,xCoord,yCoord,apDeck,objv[2],zKTag,zXTag,zBTag);
- Odie_Free((char *)xCoord);
- Odie_Free((char *)yCoord);
- Odie_Free((char *)deckCoord);
- Odie_Free((char *)apDeck);
- return TCL_OK;
- badRoute:
- Odie_Free((char *)xCoord);
- Odie_Free((char *)yCoord);
- Odie_Free((char *)deckCoord);
- Odie_Free((char *)apDeck);
- return TCL_ERROR;
- }
- /* OO Method Slicer above */
- static int OOMethod_Slicer_above(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER above NAME
- ** title: Return the deck above NAME
- */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *pDeck;
- if( objc!=3 && objc!=5 && objc!=6){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME ?x y? ?zoff?");
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&pDeck) ) return TCL_ERROR;
- if(objc==3) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pDeck->above));
- } else {
- Tcl_Obj *pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pDeck->above));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_DuplicateObj(objv[3]));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_DuplicateObj(objv[4]));
- if(objc==6) {
- Tcl_ListObjAppendElement(interp, pResult, Tcl_DuplicateObj(objv[5]));
- }
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Slicer below */
- static int OOMethod_Slicer_below(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER below NAME
- ** title: Return the deck below NAME
- */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *pDeck;
- if( objc!=3 && objc!=5 && objc!=6){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME ?x y? ?zoff?");
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&pDeck) ) return TCL_ERROR;
- if(objc==3) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pDeck->below));
- } else {
- Tcl_Obj *pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pDeck->below));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_DuplicateObj(objv[3]));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_DuplicateObj(objv[4]));
- if(objc==6) {
- Tcl_ListObjAppendElement(interp, pResult, Tcl_DuplicateObj(objv[5]));
- }
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Slicer deckid_to_name */
- static int OOMethod_Slicer_deckid_to_name(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *pDeck;
- if( objc!=3 ) {
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&pDeck) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, ODIE_CONSTANT_STRING(pDeck->zName));
- return TCL_OK;
- }
- /* OO Method Slicer deckname_to_id */
- static int OOMethod_Slicer_deckname_to_id(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *pDeck;
- if( objc!=3 ) {
- Tcl_WrongNumArgs(interp, 2, objv, "NAME");
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&pDeck) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pDeck->did));
- return TCL_OK;
- }
- /* OO Method Slicer bbox_to_location */
- static int OOMethod_Slicer_bbox_to_location(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER bbox_to_midpoint MINX MINY MINZ MAXX MAXY MAXZ
- ** title: Convert from a bounding box to IRM Coordinates of the base
- */
- Slicer *p = GETSLICER(thisObject);
- double x0, y0, z0, x1, y1, dheight;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- if (objc!=8) {
- Tcl_WrongNumArgs(interp, 2, objv, "MINX MINY MINZ MAXX MAXY MAXZ");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &z0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &x1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &y1) ) return TCL_ERROR;
- pS = Slicer_deckAt(p, x0, z0);
- dheight=z0-Slicer_deckHeight(pS,x0);
- if(dheight<0) {
- dheight=0;
- }
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pS->did));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj((x1-x0)/2+x0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj((y1-y0)/2+y0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(dheight));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer bbox_to_midpoint */
- static int OOMethod_Slicer_bbox_to_midpoint(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER bbox_to_midpoint MINX MINY MINZ MAXX MAXY MAXZ
- ** title: Convert from a bounding box to IRM Coordinates of the midpoint
- */
- Slicer *p = GETSLICER(thisObject);
- double x0, y0, z0, x1, y1, z1, dheight;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- if (objc!=8) {
- Tcl_WrongNumArgs(interp, 2, objv, "MINX MINY MINZ MAXX MAXY MAXZ");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &z0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &x1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &y1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[7], &z1) ) return TCL_ERROR;
- pS = Slicer_deckAt(p, x0, z0);
- dheight=((z1-z0)/2+z0)-Slicer_deckHeight(pS,x0);
- if (dheight<0) {
- dheight=0;
- }
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pS->did));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj((x1-x0)/2+x0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj((y1-y0)/2+y0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(dheight));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer xyz_to_location */
- static int OOMethod_Slicer_xyz_to_location(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER xyz_to_location X Y Z
- ** title: Convert from X Y Z to IRM Coordinates
- **
- ** The ABOVE-DECK parameter, if present, is the height above the deck.
- */
- Slicer *p = GETSLICER(thisObject);
- double x0, y0, z0, dheight;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- int i;
- if(objc==2) {
- Tcl_SetObjResult(interp, Tcl_NewObj());
- return TCL_OK;
- }
- if( objc < 5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y Z ?x y z?");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- for(i=2;i<objc;i+=3) {
- if( Tcl_GetDoubleFromObj(interp, objv[i], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[i+1], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[i+2], &z0) ) return TCL_ERROR;
- pS = Slicer_deckAt(p, x0, z0);
- dheight=z0-Slicer_deckHeight(pS,x0);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pS->did));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(x0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(y0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(dheight));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer location_to_xyz */
- static int OOMethod_Slicer_location_to_xyz(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Slicer *p = GETSLICER(thisObject);
- int i;
- double x0, y0, z0, dheight;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if(objc==2) {
- Tcl_SetObjResult(interp, Tcl_NewObj());
- return TCL_OK;
- }
- if( objc!= 5 && objc < 6 ){
- Tcl_WrongNumArgs(interp, 2, objv, "DECK X Y ?ZOFF? ...");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if(objc<7) {
- if( Slicer_getDeckId(interp,p,objv[2],&pS) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &y0) ) return TCL_ERROR;
- if(objc==6) {
- if( Tcl_GetDoubleFromObj(NULL, objv[5], &dheight) ) {
- dheight=0.0;
- }
- } else {
- dheight=0.0;
- }
- pResult = Tcl_NewObj();
- z0=Slicer_Location_zabs(p,pS,x0,dheight);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(x0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(y0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(z0));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- pResult = Tcl_NewObj();
- for(i=2;i<objc;i+=4) {
- if( Slicer_getDeckId(interp,p,objv[i],&pS) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[i+1], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[i+2], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(NULL, objv[i+3], &dheight) ) return TCL_ERROR;
- z0=Slicer_Location_zabs(p,pS,x0,dheight);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(x0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(y0));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(z0));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer location_z */
- static int OOMethod_Slicer_location_z(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Slicer *p = GETSLICER(thisObject);
- double x0, y0, z0, dheight;
- struct OneSlice *pS;
- if( objc!= 5 && objc!=6 ){
- Tcl_WrongNumArgs(interp, 2, objv, "DECK X Y ?ZOFF? ...");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&pS) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &y0) ) return TCL_ERROR;
- if(objc==6) {
- if( Tcl_GetDoubleFromObj(NULL, objv[5], &dheight) ) {
- dheight=0.0;
- }
- } else {
- dheight=0.0;
- }
- z0=Slicer_Location_zabs(p,pS,x0,dheight);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(z0));
- return TCL_OK;
- }
- /* OO Method Slicer distance */
- static int OOMethod_Slicer_distance(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Slicer *p = GETSLICER(thisObject);
- int d0,d1;
- double x0, y0, z0, zoff0;
- double x1, y1, z1, zoff1;
- double dx,dy,dz,distance;
- struct OneSlice *pS0;
- struct OneSlice *pS1;
- if( objc!= 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "LOCATION LOCATION");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if(Location_Base_FromTclObj(interp,objv[2],&d0,&x0,&y0,&zoff0)) return TCL_ERROR;
- if(Location_Base_FromTclObj(interp,objv[3],&d1,&x1,&y1,&zoff1)) return TCL_ERROR;
- pS0=Slicer_getDeck_FromInt(p,d0);
- if(pS0) {
- z0=Slicer_Location_zabs(p,pS0,x0,zoff0);
- } else {
- z0=zoff0;
- }
- pS1=Slicer_getDeck_FromInt(p,d1);
- if(pS1) {
- z1=Slicer_Location_zabs(p,pS1,x1,zoff1);
- } else {
- z1=zoff1;
- }
- dx=x1-x0;
- dy=y1-y0;
- dz=z1-z0;
- distance=sqrt(dx*dx+dy*dy+dz*dz);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(distance));
- return TCL_OK;
- }
- /* OO Method Slicer actualcoords */
- static int OOMethod_Slicer_actualcoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER actualcoords CANVAS-COORD-LIST ?ABOVE-DECK?
- ** title: Convert from canvas to actual coordinate space
- **
- ** The ABOVE-DECK parameter, if present, is the height above the deck.
- */
- Slicer *p = GETSLICER(thisObject);
- int i, n;
- double aboveDeck;
- Tcl_Obj *pResult;
- if( objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "CANVAS-COORD-LIST ?ABOVE-DECK?");
- return TCL_ERROR;
- }
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- if( n%2!=0 ){
- Tcl_AppendResult(interp, "coordinate list must contain a multiple "
- "of 2 values", 0);
- return TCL_ERROR;
- }
- if( objc==4 ){
- if( Tcl_GetDoubleFromObj(interp, objv[3], &aboveDeck) ) return TCL_ERROR;
- }else{
- aboveDeck = 0.0;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- for(i=0; i<n-1; i+=2){
- double ax, ay;
- double cx, cy;
- Tcl_Obj *pObj;
- int j;
- struct OneSlice *pS;
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &cx) ) break;
- Tcl_ListObjIndex(0, objv[2], i+1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &cy) ) break;
- for(j=0; j<p->nSlice-1 && p->a[j].upperbound>cy; j++){}
- pS = &p->a[j];
- /* Original Formula
- ** ax = cx*p->rZoom - pS->rXShift;
- ** ay = pS->mxY + (pS->mnY-pS->mxY)*(cy-pS->top)/(pS->btm-pS->top);
- */
- ax=Slicer_xCanvasToActual(p,pS,cx);
- ay=Slicer_yCanvasToActual(p,pS,cy);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pS->did));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(round(ax)));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(round(ay)));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(round(aboveDeck)));
- }
- if( i<n-1 ){
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer canvascoords */
- static int OOMethod_Slicer_canvascoords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER canvascoords ACTUAL-COORD-LIST ?xvar? ?yvar?
- ** title: Convert from actual (in DID X Y) to canvas coordinate space
- **
- ** The coordinates are considered to form a line. If the actual
- ** coordinates make a transition from one slice to another, an extra
- ** set of canvas coordinates may be inserted to show the point of
- ** this transition.
- **
- */
- Slicer *p = GETSLICER(thisObject);
- int i, n;
- Tcl_Obj *pResult=NULL;
- double ax, ay;
- double cx, cy;
- Tcl_Obj *pObj;
- struct OneSlice *pS;
- int error=0;
- if( objc!=3 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ACTUAL-COORD-LIST ?xvar yvar?");
- return TCL_ERROR;
- }
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- if(n==3) {
- /* Goose a 3 length to a 4 length */
- n=4;
- }
- if(n<4 || n%4!=0) {
- Tcl_AppendResult(interp, "coordinate list must contain a multiple "
- "of 4 values", 0);
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if(objc != 5) {
- pResult = Tcl_NewObj();
- }
- for(i=0; i<n-3; i+=4){
- Tcl_ListObjIndex(0, objv[2], i+1, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &ax) ) {
- error=1;
- break;
- }
- Tcl_ListObjIndex(0, objv[2], i+2, &pObj);
- if( Tcl_GetDoubleFromObj(interp, pObj, &ay) ) {
- error=1;
- break;
- }
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if( Slicer_getDeckId(interp, p, pObj, &pS) ) {
- error=1;
- break;
- }
- /* Old direct formula
- **
- ** cx = (ax+pS->rXShift)/p->rZoom;
- ** cy = pS->top + (pS->btm-pS->top)*(ay-pS->mxY)/(pS->mnY-pS->mxY);
- */
- cx = Slicer_xActualToCanvas(p,pS,ax);
- cy = Slicer_yActualToCanvas(p,pS,ay);
- if(objc==5) {
- Tcl_ObjSetVar2(interp,objv[3],NULL,Tcl_NewDoubleObj(cx),0);
- Tcl_ObjSetVar2(interp,objv[4],NULL,Tcl_NewDoubleObj(cy),0);
- return TCL_OK;
- } else {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(cx));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(cy));
- }
- }
- if(error) {
- if(pResult) {
- Tcl_DecrRefCount(pResult);
- }
- return TCL_ERROR;
- }
- if( i<n-3 ){
- Tcl_AppendResult(interp, "Did not reach the end", 0);
- Tcl_DecrRefCount(pResult);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer create */
- static int OOMethod_Slicer_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER create DID NAME Z MIN-Y MAX-Y
- ** title: Create a new slice
- */
- Slicer *p = GETSLICER(thisObject);
- double z, mnY, mxY;
- const char *zNameOrig;
- char *zName;
- int did;
- int i, nName;
- if( objc!=7 ){
- Tcl_WrongNumArgs(interp, 2, objv, "DID NAME Z MIN-Y MAX-Y");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &did) ) return TCL_ERROR;
- zNameOrig = Tcl_GetStringFromObj(objv[3], &nName);
- if( Tcl_GetDoubleFromObj(interp, objv[4], &z) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &mnY) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[6], &mxY) ) return TCL_ERROR;
- if( mnY>=mxY ){
- Tcl_AppendResult(interp, "MIN-Y must be less than MAX-Y", 0);
- return TCL_ERROR;
- }
- zName = Odie_Alloc( nName+1 );
- if( zName==0 ) return TCL_ERROR;
- memcpy(zName, zNameOrig, nName+1);
- for(i=0; i<p->nSlice; i++){
- if( p->a[i].did==did ){
- Tcl_AppendResult(interp, "Deckid for slice ", zName, " is the "
- "same as existing slice ", p->a[i].zName, 0);
- return TCL_ERROR;
- }
- if( p->a[i].z==z ){
- Tcl_AppendResult(interp, "Z coordinate for slice ", zName, " is the "
- "same as existing slice ", p->a[i].zName, 0);
- return TCL_ERROR;
- }
- }
- p->nSlice++;
- p->a = (OneSlice *)Tcl_Realloc((char *)p->a, sizeof(p->a[0])*p->nSlice);
- if( p->a==0 ){
- p->nSlice = 0;
- return TCL_ERROR;
- }
- for(i=p->nSlice-1; i>0 && p->a[i-1].z>z; i--){
- p->a[i] = p->a[i-1];
- p->a[i].idx = i;
- }
- p->a[i].did = did;
- p->a[i].idx = i;
- p->a[i].zName = zName;
- p->a[i].nXZ = 0;
- p->a[i].xz = 0;
- p->a[i].z = z;
- p->a[i].mnY = mnY;
- p->a[i].mxY = mxY;
- p->a[i].rXShift = p->rXOffset*z;
- Slicer_computeTopAndBottom(p);
- return TCL_OK;
- }
- /* OO Method Slicer deck_at_xyz */
- static int OOMethod_Slicer_deck_at_xyz(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER deck X Y Z
- ** title: Return the name of the deck at actual coordinates X,Y,Z
- **
- ** See also: find
- */
- Slicer *p = GETSLICER(thisObject);
- double x0, y0, z0;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y Z");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &z0) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- pS = Slicer_deckAt(p, x0, z0);
- pResult = ODIE_CONSTANT_STRING(pS->zName);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer deckid_at_xyx */
- static int OOMethod_Slicer_deckid_at_xyx(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER did X Y Z
- ** title: Return the id of the deck at actual coordinates X,Y,Z
- **
- ** See also: find
- */
- Slicer *p = GETSLICER(thisObject);
- double x0, y0, z0;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y Z");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &z0) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- pS = Slicer_deckAt(p, x0, z0);
- pResult = Tcl_NewIntObj(pS->did);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer delete */
- static int OOMethod_Slicer_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER delete NAME
- ** title: Remove a slice from the slicer
- */
- Slicer *p = GETSLICER(thisObject);
- int i, j;
- const char *zName;
- if( objc!=2 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME");
- return TCL_ERROR;
- }
- zName = Tcl_GetStringFromObj(objv[2], 0);
- for(i=0; i<p->nSlice && strcmp(p->a[i].zName,zName)!=0; i++){}
- if( i<p->nSlice ){
- Odie_Free((char *)p->a[i].zName);
- p->nSlice--;
- for(j=i; j<p->nSlice; j++){
- p->a[j] = p->a[j+1];
- }
- Slicer_computeTopAndBottom(p);
- }
- return TCL_OK;
- }
- /* OO Method Slicer makedlist */
- static int OOMethod_Slicer_makedlist(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER makedlist CANVAS ACTUAL-PATH TAG TRANSDECK-TAG P-TAG ?COLOR?
- ** title: Return TK to draw a line on a canvas
- */
- Slicer *p = GETSLICER(thisObject);
- int i, n;
- double *aCoord; /* Actual coordinates of line to draw */
- struct OneSlice **apDeck; /* Array of all decks */
- Tcl_Obj *pVTag; /* The "sNNN" tag added to all line segments */
- const char *zXTag; /* Trans-deck tag (dashed lines) */
- Tcl_Obj *rtnList ; /* List object to return */
- Tcl_Obj *coordList ; /* List of coords to return */
- Tcl_Obj *configList ; /* configuration string to return */
- Tcl_Obj *tmpObj; /* Cheater for filling lists */
- if( objc!=5 && objc!=6 ){
- Tcl_WrongNumArgs(interp, 2, objv,
- "ACTUAL-PATH TAG TRANSDECK-TAG ?COLOR?");
- return TCL_ERROR;
- }
- // slicer makedlist Path TagList Transdeck-TagList ?COLOR?
- // 0 1 2 3 4 5
- zXTag = Tcl_GetStringFromObj(objv[4], 0);
- if( Tcl_ListObjLength(interp, objv[2], &n) ) return TCL_ERROR;
- if( n%3!=0 || n<6 ){
- Tcl_AppendResult(interp, "coordinate list must contain a multiple "
- "of 3 values with a minimum of 6", 0);
- return TCL_ERROR;
- }
- rtnList = Tcl_NewListObj(0, NULL);
- aCoord = (double *)Odie_Alloc( sizeof(aCoord[0])*n + sizeof(apDeck[0])*(n/3) );
- if( aCoord==0 ){
- return TCL_ERROR;
- }
- // Move coords from Tcl objv[3] int "C" aCoord array
- apDeck = (struct OneSlice **)&aCoord[n];
- for(i=0; i<n; i++){
- Tcl_Obj *pObj;
- Tcl_ListObjIndex(0, objv[2], i, &pObj);
- if( Odie_GetMatrixElementFromObj(interp, pObj, aCoord, i) ){
- Odie_Free((char *)aCoord);
- return TCL_ERROR;
- }
- }
- n /= 3;
- for(i=0; i<n; i++){
- double z = aCoord[i*3+2];
- double x = aCoord[i*3];
- apDeck[i] = Slicer_deckAt(p, x, z);
- }
- for(i=1; i<n; i++){
- char zBuf[30];
- double x0, y0, x1, y1, Y0, Y1;
- coordList = Tcl_NewListObj(0, NULL);
- configList = Tcl_NewListObj(0, NULL);
- sprintf(zBuf, "s%d", i);
- pVTag = Tcl_NewStringObj(zBuf, -1);
- if( apDeck[i]!=apDeck[i-1] ) {
- /* Old direct formula
- **
- ** x0=(aCoord[i*3-3]+apDeck[i-1]->rXShift)/p->rZoom;
- ** x1 = (aCoord[i*3]+apDeck[i]->rXShift)/p->rZoom;
- */
- x0 = Slicer_xActualToCanvas(p,apDeck[i-1],aCoord[i*3-3]);
- x1 = Slicer_xActualToCanvas(p,apDeck[i],aCoord[i*3]);
- y0 = Slicer_yActualToCanvas(p,apDeck[i-1], Y0=aCoord[i*3-2]);
- y1 = Slicer_yActualToCanvas(p,apDeck[i], Y1=aCoord[i*3+1]);
- if( zXTag[0]!=0 ){
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(x0));
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(y0));
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(x1));
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(y1));
- Tcl_ListObjAppendElement(interp, configList,
- ODIE_CONSTANT_STRING("-tags"));
- tmpObj = Tcl_DuplicateObj(objv[4]);
- Tcl_ListObjAppendElement(interp, tmpObj, pVTag);
- Tcl_ListObjAppendElement(interp, configList, tmpObj);
- }
- } else {
- /* Old direct formula
- **
- ** x0 = (aCoord[i*3-3]+apDeck[i]->rXShift)/p->rZoom;
- ** x1 = (aCoord[i*3]+apDeck[i]->rXShift)/p->rZoom;
- */
- x0 = Slicer_xActualToCanvas(p,apDeck[i],aCoord[i*3-3]);
- x1 = Slicer_xActualToCanvas(p,apDeck[i],aCoord[i*3]);
- y0 = Slicer_yActualToCanvas(p,apDeck[i], aCoord[i*3-2]);
- y1 = Slicer_yActualToCanvas(p,apDeck[i], aCoord[i*3+1]);
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(x0));
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(y0));
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(x1));
- Tcl_ListObjAppendElement(interp, coordList,Tcl_NewDoubleObj(y1));
- Tcl_ListObjAppendElement(interp, configList, ODIE_CONSTANT_STRING("-tags"));
- tmpObj = Tcl_DuplicateObj(objv[3]);
- Tcl_ListObjAppendElement(interp, tmpObj, pVTag);
- Tcl_ListObjAppendElement(interp, configList, tmpObj);
- }
- if( objc>=6 ) {
- Tcl_ListObjAppendElement(interp, configList, ODIE_CONSTANT_STRING("-fill"));
- Tcl_ListObjAppendElement(interp, configList, Tcl_DuplicateObj(objv[5]));
- }
- Tcl_ListObjAppendElement(interp, rtnList, coordList);
- Tcl_ListObjAppendElement(interp, rtnList, configList);
- }
- Odie_Free((char *)aCoord);
- Tcl_SetObjResult(interp, rtnList);
- return TCL_OK;
- }
- /* OO Method Slicer find */
- static int OOMethod_Slicer_find(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* tclmethod: SLICER find X Y
- ** title: Return the name of the deck at canvas coordinates X,Y
- **
- ** The "deck" command works similarly except that it uses actual
- ** coordinates as inputs.
- */
- Slicer *p = GETSLICER(thisObject);
- int i;
- double x0, y0;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nSlice-1 && p->a[i].upperbound>y0; i++){}
- pS = &p->a[i];
- pResult = ODIE_CONSTANT_STRING(pS->zName);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer finddid */
- static int OOMethod_Slicer_finddid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER finddid X Y
- ** title: Return the name of the deck at canvas coordinates X,Y
- **
- ** The "deck" command works similarly except that it uses actual
- ** coordinates as inputs.
- */
- Slicer *p = GETSLICER(thisObject);
- int i;
- double x0, y0;
- Tcl_Obj *pResult;
- struct OneSlice *pS;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nSlice-1 && p->a[i].upperbound>y0; i++){}
- pS = &p->a[i];
- pResult = Tcl_NewIntObj(pS->did);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer flatheight */
- static int OOMethod_Slicer_flatheight(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER flatheight NAME ?X?
- ** title: Return the flatheight of slice NAME at actual position X
- ** Assuming the deck were flat
- **
- ** See also "headroom".
- */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *ppS;
- //double x0;
- if( objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME ?X?");
- return TCL_ERROR;
- }
- //if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if( Slicer_getDeckId(interp,p,objv[2],&ppS) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(ppS->z));
- return TCL_OK;
- }
- /* OO Method Slicer headroom */
- static int OOMethod_Slicer_headroom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER headroom NAME X
- ** title: Return the headroom (Z from deck) of slice NAME at actual position X
- **
- ** See also "height"
- */
- Slicer *p = GETSLICER(thisObject);
- double x0;
- struct OneSlice *pDeck, *pAbove;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME X");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if( Slicer_getDeckId(interp,p,objv[2],&pDeck) ) return TCL_ERROR;
- pAbove = Slicer_deckAbove(p, pDeck);
- if( pAbove ){
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(Slicer_deckHeight(pAbove,x0)-Slicer_deckHeight(pDeck,x0)));
- }else{
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(p->upper_height));
- }
- return TCL_OK;
- }
- /* OO Method Slicer ceiling */
- static int OOMethod_Slicer_ceiling(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER ceiling NAME X ?DEFAULT?
- ** title: Return the Z (absolute) of the ceiling of slice NAME at actual position X
- **
- ** See also "height"
- */
- Slicer *p = GETSLICER(thisObject);
- double x0;
- struct OneSlice *pDeck, *pAbove;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME X");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if( Slicer_getDeckId(interp,p,objv[2],&pDeck) ) return TCL_ERROR;
- pAbove = Slicer_deckAbove(p, pDeck);
- if( pAbove ){
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(Slicer_deckHeight(pAbove,x0)));
- }else{
- Tcl_SetObjResult(interp,Tcl_NewDoubleObj(Slicer_deckHeight(pDeck,x0)+p->upper_height));
- }
- return TCL_OK;
- }
- /* OO Method Slicer height */
- static int OOMethod_Slicer_height(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER height NAME X ?zoff?
- ** title: Return the height (absolute) of slice NAME at actual position X
- ** description:
- ** NOTE if the top deck is asked for, and zoff is negative the
- ** system will assume a 2000mm ceiling
- ** See also "headroom".
- */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *ppS,*pAbove;
- double x0,zoff=0,zresult=0.0;
- if( objc!=4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME X ?ZOFF?");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if( Slicer_getDeckId(interp,p,objv[2],&ppS) ) return TCL_ERROR;
- if( objc==5 ) {
- if( Tcl_GetDoubleFromObj(NULL, objv[4], &zoff) ) {
- zoff=0.0;
- }
- }
- if(zoff < 0.0) {
- pAbove = Slicer_deckAbove(p, ppS);
- if(pAbove) {
- zresult=Slicer_deckHeight(pAbove,x0)+zoff;
- } else {
- zresult=Slicer_deckHeight(ppS,x0)+2000+zoff;
- }
- } else {
- zresult=Slicer_deckHeight(ppS,x0)+zoff;
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(zresult));
- return TCL_OK;
- }
- /* OO Method Slicer deckheight */
- static int OOMethod_Slicer_deckheight(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER deckheight NAME X ?zoff?
- ** title: Return the height (mm from floor) of slice NAME at actual position X
- ** description:
- ** NOTE if the top deck is asked for, and zoff is negative the
- ** system will assume a 2000mm ceiling
- ** See also "headroom".
- */
- Slicer *p = GETSLICER(thisObject);
- double x0, z0, dheight;
- struct OneSlice *pS;
- if( objc!= 4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "DECK X ?ZOFF?");
- return TCL_ERROR;
- }
- if( p->nSlice<=0 ){
- Tcl_AppendResult(interp, "no slices defined", 0);
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&pS) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x0) ) return TCL_ERROR;
- if(objc==5) {
- if( Tcl_GetDoubleFromObj(NULL, objv[4], &dheight) ) {
- dheight=0.0;
- }
- } else {
- dheight=0.0;
- }
- z0=Location_zdeck(p,pS,x0,dheight);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(z0));
- return TCL_OK;
- }
- /* OO Method Slicer info */
- static int OOMethod_Slicer_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER info NAME
- ** title: Return information about a particular slice
- */
- Slicer *p = GETSLICER(thisObject);
- struct OneSlice *ppS;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME|DECKID");
- return TCL_ERROR;
- }
- if( Slicer_getDeckId(interp,p,objv[2],&ppS) ) {
- return TCL_ERROR;
- } else {
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("name"));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING(ppS->zName));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("did"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(ppS->did));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("z"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->z));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("miny"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->mnY));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("maxy"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->mxY));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("top"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->top));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("bottom"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->btm));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("above"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->above));
- Tcl_ListObjAppendElement(interp, pResult, ODIE_CONSTANT_STRING("below"));
- Tcl_ListObjAppendElement(interp, pResult, Tcl_NewDoubleObj(ppS->below));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Slicer list */
- static int OOMethod_Slicer_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER list
- ** title: List the names of all defined slices in the slicer
- */
- Slicer *p = GETSLICER(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- int i;
- for(i=0; i<p->nSlice; i++){
- Tcl_ListObjAppendElement(0, pResult, ODIE_CONSTANT_STRING(p->a[i].zName));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Slicer profile */
- static int OOMethod_Slicer_profile(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER profile DECK ?X Z ...?
- ** title: Create an inboard profile for a deck
- */
- Slicer *p = GETSLICER(thisObject);
- int i, j, min;
- struct OneSlice *pS;
- if( objc<3 || (objc>3 && objc<7) || (objc & 1)==0 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME ?X Z X Z...?");
- return TCL_ERROR;
- }
- if(Slicer_getDeckId(interp,p,objv[2],&pS)) {
- return TCL_ERROR;
- }
- if( objc==3 ){
- Tcl_Obj *pResult = Tcl_NewObj();
- for(i=0; i<pS->nXZ; i++){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pS->xz[i]));
- }
- Tcl_SetObjResult(interp, pResult);
- }else{
- double *xz;
- if( pS->xz ) Odie_Free((char *)pS->xz);
- pS->nXZ = objc - 3;
- xz = pS->xz = (double *)Odie_Alloc( sizeof(pS->xz[0])*pS->nXZ );
- if( xz==0 ){
- pS->nXZ = 0;
- return TCL_OK;
- }
- for(i=0; i<pS->nXZ; i++){
- if( Odie_GetMatrixElementFromObj(interp, objv[i+3], xz, i) ){
- Odie_Free((char *)xz);
- pS->nXZ = 0;
- pS->xz = 0;
- return TCL_ERROR;
- }
- }
- /* Put the profile in increasing X order. An N**2 sort is used because
- ** it is convenient and the list will usually be short. */
- for(i=0; i<pS->nXZ-2; i+=2){
- for(min=i, j=i+2; j<pS->nXZ; j+=2){
- if( xz[j]<xz[min] ) min = j;
- }
- if( min>i ){
- double t = xz[min];
- xz[min] = xz[i];
- xz[i] = t;
- t = xz[min+1];
- xz[min+1] = xz[i+1];
- xz[i+1] = t;
- }
- }
- /* Remove duplidate X coordinates */
- for(i=j=0; i<pS->nXZ; i+=2){
- if( i<pS->nXZ-2 && xz[i+2]==xz[i] ){
- /* Ignore the duplicate */
- }else{
- xz[j++] = xz[i];
- xz[j++] = xz[i+1];
- }
- }
- pS->nXZ = j;
- if( j<4 ){
- pS->nXZ = 0;
- Odie_Free((char *)pS->xz);
- pS->xz = 0;
- }
- }
- return TCL_OK;
- }
- /* OO Method Slicer xoffset */
- static int OOMethod_Slicer_xoffset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER xoffset ?AMT?
- ** title: Change the X-Offset as a function of deck height
- */
- Slicer *p = GETSLICER(thisObject);
- double rXOffset;
- int i;
- if( objc!=2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?XOFFSET?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- if( Tcl_GetDoubleFromObj(interp, objv[2], &rXOffset) ) return TCL_ERROR;
- for(i=0; i<p->nSlice; i++){
- p->a[i].rXShift = rXOffset*p->a[i].z;
- }
- p->rXOffset = rXOffset;
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(p->rXOffset));
- return TCL_OK;
- }
- /* OO Method Slicer zoom */
- static int OOMethod_Slicer_zoom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER zoom ?ZOOM?
- ** title: Query or change the zoom factor.
- */
- Slicer *p = GETSLICER(thisObject);
- if( objc!=2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?ZOOM?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- double r;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &r) ) return TCL_ERROR;
- p->rZoom = r;
- Slicer_computeTopAndBottom(p);
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(p->rZoom));
- return TCL_OK;
- }
- /* OO Method Slicer upper_height */
- static int OOMethod_Slicer_upper_height(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: SLICER upper_height MM
- ** title: Set the headroom on the top level of the slicer (defaults to 2000)
- */
- Slicer *p = GETSLICER(thisObject);
- if( objc != 2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?Z?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- double r;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &r) ) return TCL_ERROR;
- p->upper_height=r;
- }
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(p->upper_height));
- return TCL_OK;
- }
- /* OO Method Slicer Slicer_Init */
- static int OOMethod_Slicer_Slicer_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Slicer *p;
- p = (Slicer *)Odie_Alloc( sizeof(*p) );
- p->rZoom = 100;
- p->upper_height=2000;
- Tcl_ObjectSetMetadata(thisObject, &SlicerDataType, (ClientData) p);
- return TCL_OK;
- }
- /* Loader for Slicer */
- static int Slicer_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::slicer" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::slicer" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::slicer", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- nameObj=Tcl_NewStringObj("drawline",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_drawline, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("above",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_above, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("below",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_below, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deckid_to_name",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deckid_to_name, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deckname_to_id",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deckname_to_id, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("bbox_to_location",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_bbox_to_location, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("bbox_to_midpoint",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_bbox_to_midpoint, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("xyz_to_location",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_xyz_to_location, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("location_to_xyz",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_location_to_xyz, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("location_z",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_location_z, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("distance",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_distance, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("actualcoords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_actualcoords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("canvascoords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_canvascoords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("create",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deck_at_xyz",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deck_at_xyz, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deck",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deck_at_xyz, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deckid_at_xyx",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deckid_at_xyx, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("did",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deckid_at_xyx, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deckid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deckid_at_xyx, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("makedlist",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_makedlist, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("find",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_find, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("finddid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_finddid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("flatheight",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_flatheight, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("headroom",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_headroom, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("ceiling",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_ceiling, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("height",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_height, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deckheight",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_deckheight, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("info",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_info, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("profile",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_profile, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("xoffset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_xoffset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("zoom",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_zoom, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("upper_height",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_upper_height, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("Slicer_Init",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Slicer_Slicer_Init, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* OO Method Wallset atvertex */
- static int OOMethod_Wallset_atvertex(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET atvertex X Y
- ** title: Return a list of wall IDs that connect to vertex X,Y
- */
- Wallset *p = GETWALLSET(thisObject);
- Link *pList;
- double x, y;
- Tcl_Obj *pResult;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- ignoreNone(p);
- pList = segmentsAtVertex(p, x*p->rXZoom, y*p->rYZoom);
- while( pList ){
- Segment *pSeg=pList->pLinkNode;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- pList = pList->pNext;
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset boundary */
- static int OOMethod_Wallset_boundary(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET boundary X Y
- ** title: Return indices of segments forming a boundary around X Y
- */
- Wallset *p = GETWALLSET(thisObject);
- Boundary aBound[MX_BOUND];
- int nBound;
- double x, y;
- Tcl_Obj *pResult;
- int i;
- int showDetail = 0;
- if( objc==5 && strcmp(Tcl_GetStringFromObj(objv[2],0),"-detail")==0 ){
- showDetail = 1;
- objc--;
- objv++;
- }
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?-detail? X Y");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y) ) return TCL_ERROR;
- nBound = findBoundary(p, x*p->rXZoom, y*p->rYZoom, MX_BOUND, aBound);
- if( nBound>MX_BOUND ) nBound = 0;
- pResult = Tcl_NewObj();
- for(i=0; i<nBound; i++){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(aBound[i].pSeg->id));
- if( showDetail ){
- Tcl_ListObjAppendElement(0, pResult,
- ODIE_CONSTANT_STRING(aBound[i].backwards ? "right" : "left"));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset closure */
- static int OOMethod_Wallset_closure(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET closure WALLID BACKWARDS CHECKPRIMARY ?-coords?
- ** title: Return the closure of a wall
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- Wallset *p = GETWALLSET(thisObject);
- Boundary aBound[MX_BOUND];
- int id;
- int nBound, i, checkPrim;
- Tcl_Obj *pResult;
- int coordsFlag = 0;
- int noerrFlag = 0;
- if( objc!=5 && objc!=6 ){
- Tcl_WrongNumArgs(interp, 2, objv,
- "WALLID BACKWARDS CHECKPRIMARY ?-coords? ?-noerr?");
- return TCL_ERROR;
- }
- if( objc==6 ){
- const char *zOpt = Tcl_GetStringFromObj(objv[5],0);
- if( strcmp(zOpt,"-coords")==0 ){
- coordsFlag = 1;
- }else if( strcmp(zOpt,"-noerr")==0 ){
- noerrFlag = 1;
- }else{
- Tcl_AppendResult(interp, "unknown option: ", zOpt, 0);
- return TCL_ERROR;
- }
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (aBound[0].pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[3], &aBound[0].backwards) ){
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[4], &checkPrim) ){
- return TCL_ERROR;
- }
- ignoreNone(p);
- nBound = completeBoundary(p, checkPrim, MX_BOUND, aBound);
- pResult = Tcl_NewObj();
- if( nBound<0 && noerrFlag ) nBound = -nBound;
- for(i=0; i<nBound; i++){
- if( coordsFlag ){
- double x, y;
- Segment *pSeg = aBound[i].pSeg;
- if( aBound[i].backwards ){
- x = pSeg->to[X_IDX];
- y = pSeg->to[Y_IDX];
- }else{
- x = pSeg->from[X_IDX];
- y = pSeg->from[Y_IDX];
- }
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(x/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(y/p->rYZoom));
- }else{
- Tcl_ListObjAppendElement(0, pResult,
- Tcl_NewIntObj(aBound[i].pSeg->id));
- Tcl_ListObjAppendElement(0, pResult,
- ODIE_CONSTANT_STRING(aBound[i].backwards ? "right" : "left"));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset closure_polygon */
- static int OOMethod_Wallset_closure_polygon(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET closure_polygon WALLID BACKWARDS CHECKPRIMARY
- ** title: Return the closure of a wall
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- Wallset *p = GETWALLSET(thisObject);
- Boundary aBound[MX_BOUND];
- int id;
- int nBound, i, checkPrim;
- Tcl_Obj *pResult;
- int noerrFlag = 0;
- Odie_Polygon *pPolyOut;
- if( objc!=5 && objc!=6 ){
- Tcl_WrongNumArgs(interp, 2, objv,
- "WALLID BACKWARDS CHECKPRIMARY ?-noerr?");
- return TCL_ERROR;
- }
- if( objc==6 ){
- const char *zOpt = Tcl_GetStringFromObj(objv[5],0);
- if( strcmp(zOpt,"-noerr")==0 ){
- noerrFlag = 1;
- }else{
- Tcl_AppendResult(interp, "unknown option: ", zOpt, 0);
- return TCL_ERROR;
- }
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (aBound[0].pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[3], &aBound[0].backwards) ){
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[4], &checkPrim) ){
- return TCL_ERROR;
- }
- ignoreNone(p);
- nBound = completeBoundary(p, checkPrim, MX_BOUND, aBound);
- pResult = Tcl_NewObj();
- if( nBound<0 && noerrFlag ) nBound = -nBound;
- pPolyOut=Odie_FaceXYZ_Create(nBound+1);
- pPolyOut->nVertex=nBound;
- for(i=0; i<nBound; i++){
- Segment *pSeg = aBound[i].pSeg;
- if( aBound[i].backwards ){
- VectorXYZ_Copy(pPolyOut->v[i],pSeg->to);
- }else{
- VectorXYZ_Copy(pPolyOut->v[i],pSeg->from);
- }
- }
- Odie_Polygon_ComputeArea(interp,pPolyOut);
- Tcl_SetObjResult(interp, Odie_Polygon_NewTclObj(pPolyOut));
- return TCL_OK;
- }
- /* OO Method Wallset closure_check */
- static int OOMethod_Wallset_closure_check(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET closure_check WALLID BACKWARDS
- ** title: Return the closure of a wall
- **
- ** The closure is a path of walls going clockwise from the wall given.
- ** The return value is a list consisting of wall IDs alternating with
- ** keywords "left" or "right" indicating which side of the wall applies.
- ** If the CHECKPRIMARY flag is true and the WALLID/BACKWARDS is not the
- ** primary wall id for the closure, then return an empty string. The
- ** primary wall id is the wall id with the lowest id number, or if
- ** two walls in the closure have the same id, then the one that goes
- ** on the right side of the wall.
- */
- Wallset *p = GETWALLSET(thisObject);
- Boundary aBound[MX_BOUND];
- int id;
- int nBound, i, checkPrim;
- Tcl_Obj *pResult;
- int noerrFlag = 0;
- if( objc!=5){
- Tcl_WrongNumArgs(interp, 2, objv,
- "WALLID BACKWARDS CHECKPRIMARY");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (aBound[0].pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[3], &aBound[0].backwards) ){
- return TCL_ERROR;
- }
- if( Tcl_GetBooleanFromObj(interp, objv[4], &checkPrim) ){
- return TCL_ERROR;
- }
- ignoreNone(p);
- nBound = completeBoundary(p, 0, MX_BOUND, aBound);
- pResult = Tcl_NewObj();
- if( nBound<0 && noerrFlag ) nBound = -nBound;
- for(i=0; i<nBound; i++) {
- Tcl_ListObjAppendElement(0, pResult,
- Tcl_NewIntObj(aBound[i].pSeg->id));
- Tcl_ListObjAppendElement(0, pResult,
- Tcl_NewIntObj(aBound[i].backwards));
- if(aBound[i].backwards) {
- Tcl_ListObjAppendElement(0, pResult,
- Tcl_NewIntObj(aBound[i].pSeg->idLC));
- } else {
- Tcl_ListObjAppendElement(0, pResult,
- Tcl_NewIntObj(aBound[i].pSeg->idRC));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset comptlist */
- static int OOMethod_Wallset_comptlist(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET comptlist
- ** title: Return a list of all compartments
- **
- ** A compartment is a closed circuit of walls. This routine returns
- ** a list of all compartments. Each element of the list consists of
- ** the primary wall for the compartment followed by a bounding box
- ** for the compartment.
- */
- Wallset *p = GETWALLSET(thisObject);
- ComptBox *pBox;
- Tcl_Obj *pResult = Tcl_NewObj();
- buildComptBoxCache(p);
- for(pBox=p->pComptBox; pBox; pBox=pBox->pNext){
- Tcl_Obj *pElem = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pElem,Tcl_NewIntObj(pBox->prim.pSeg->id));
- Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pBox->prim.backwards));
- Tcl_ListObjAppendElement(0, pElem, Tcl_NewDoubleObj(pBox->bbox[BBOX_X0_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, pElem, Tcl_NewDoubleObj(pBox->bbox[BBOX_Y0_IDX]/p->rYZoom));
- Tcl_ListObjAppendElement(0, pElem, Tcl_NewDoubleObj(pBox->bbox[BBOX_X1_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, pElem, Tcl_NewDoubleObj(pBox->bbox[BBOX_Y1_IDX]/p->rYZoom));
- Tcl_ListObjAppendElement(0, pResult, pElem);
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset corners */
- static int OOMethod_Wallset_corners(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET corners X Y
- ** title: Return vertices of compartment containing X,Y
- */
- Wallset *p = GETWALLSET(thisObject);
- Boundary aBound[MX_BOUND];
- int nBound, i;
- double x, y;
- Tcl_Obj *pResult;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y) ) return TCL_ERROR;
- nBound = findBoundary(p, x*p->rXZoom, y*p->rYZoom, MX_BOUND, aBound);
- if( nBound>MX_BOUND ) nBound = 0;
- pResult = Tcl_NewObj();
- for(i=0; i<nBound; i++){
- Segment *pSeg = aBound[i].pSeg;
- if( aBound[i].backwards ){
- x = pSeg->to[X_IDX];
- y = pSeg->to[Y_IDX];
- }else{
- x = pSeg->from[X_IDX];
- y = pSeg->from[Y_IDX];
- }
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(x/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(y/p->rYZoom));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset delete */
- static int OOMethod_Wallset_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET delete ID
- ** title: Delete a single segment of a wall given by ID
- */
- Wallset *p = GETWALLSET(thisObject);
- int id;
- Segment *pSeg;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( p->busy ){
- Tcl_AppendResult(interp, "cannot \"delete\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- clearComptBoxCache(p);
- LinkRemove(&pSeg->pAll);
- /* We intentionally do not remove pSeg->pSet because it might not be
- ** a well-formed list */
- LinkRemove(&pSeg->pHash);
- LinkRemove(&pSeg->pFrom);
- LinkRemove(&pSeg->pTo);
- Tcl_Free((char *)pSeg);
- return TCL_OK;
- }
- /* OO Method Wallset firstboundary */
- static int OOMethod_Wallset_firstboundary(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET firstboundary X Y
- ** title: Find a wall on the boundary of compartment containing X Y
- **
- ** Returns a list of two elements on success or an empty list if no
- ** suitable boundary could be found. The first element is the ID of a
- ** wall that forms part of the boundary for the compartment containing
- ** point X,Y. The second element is TRUE if X,Y is to the right of the
- ** wall and false if it is to the left.
- **
- ** The right/left designation assumes a right-handed coordinate system.
- */
- Wallset *p = GETWALLSET(thisObject);
- int isBack;
- Segment *pSeg;
- double x, y;
- int rc;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "X Y");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y) ) return TCL_ERROR;
- ignoreNone(p);
- rc = firstBoundarySegment(p, x*p->rXZoom, y*p->rYZoom, &pSeg, &isBack);
- if( rc==0 ){
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(isBack));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Wallset foreach */
- static int OOMethod_Wallset_foreach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET foreach CODE
- ** title: Run CODE for each segment of the wallset
- */
- Wallset *p = GETWALLSET(thisObject);
- Link *pLink;
- int rc = TCL_OK;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "CODE");
- return TCL_ERROR;
- }
- p->busy++;
- for(pLink=p->pAll; pLink && rc==TCL_OK; pLink=pLink->pNext){
- Segment *pSeg = pLink->pLinkNode;
- Tcl_SetVar2Ex(interp, "x0", 0, Tcl_NewDoubleObj(pSeg->from[X_IDX]/p->rXZoom), 0);
- Tcl_SetVar2Ex(interp, "y0", 0, Tcl_NewDoubleObj(pSeg->from[Y_IDX]/p->rYZoom), 0);
- Tcl_SetVar2Ex(interp, "x1", 0, Tcl_NewDoubleObj(pSeg->to[X_IDX]/p->rXZoom), 0);
- Tcl_SetVar2Ex(interp, "y1", 0, Tcl_NewDoubleObj(pSeg->to[Y_IDX]/p->rYZoom), 0);
- Tcl_SetVar2Ex(interp, "id", 0, Tcl_NewIntObj(pSeg->id), 0);
- Tcl_SetVar2Ex(interp, "lc", 0, Tcl_NewIntObj(pSeg->idLC), 0);
- Tcl_SetVar2Ex(interp, "rc", 0, Tcl_NewIntObj(pSeg->idRC), 0);
- Tcl_SetVar2Ex(interp, "virtual", 0, Tcl_NewIntObj(pSeg->isBoundary), 0);
- rc = Tcl_EvalObjEx(interp, objv[2], 0);
- }
- if( rc==TCL_BREAK ) rc = TCL_OK;
- p->busy--;
- return rc;
- }
- /* OO Method Wallset info */
- static int OOMethod_Wallset_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET info ID
- ** title: Return information about a single wall segment
- */
- Wallset *p = GETWALLSET(thisObject);
- int id;
- Segment *pSeg;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->from[X_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->from[Y_IDX]/p->rYZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->to[X_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->to[Y_IDX]/p->rYZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->idLC));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->idRC));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset rawinfo */
- static int OOMethod_Wallset_rawinfo(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET info ID
- ** title: Return information about a single wall segment
- */
- Wallset *p = GETWALLSET(thisObject);
- int id;
- Segment *pSeg;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( (pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->from[X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->from[Y_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->to[X_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(pSeg->to[Y_IDX]));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->idLC));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->idRC));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset insert */
- static int OOMethod_Wallset_insert(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET insert X0 Y0 X1 Y1 ID LC RC VIRTUAL
- ** title: Create a new wall within the wallset
- */
- Wallset *p = GETWALLSET(thisObject);
- int id;
- int h,virtual=0;
- double x0, y0, x1, y1;
- int idLC, idRC;
- Segment *pSeg;
- if( objc!=9 && objc!=10){
- Tcl_WrongNumArgs(interp, 2, objv, "X0 Y0 X1 Y1 ID LC RC ?1|0?");
- return TCL_ERROR;
- }
- if( p->busy ){
- Tcl_AppendResult(interp, "cannot \"insert\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &x1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &y1) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[6], &id) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[7], &idLC) ) {
- Tcl_ResetResult(interp);
- idLC=0;
- }
- if( Tcl_GetIntFromObj(interp, objv[8], &idRC) ) {
- Tcl_ResetResult(interp);
- idRC=0;
- }
- if(objc==10) {
- if( Tcl_GetIntFromObj(interp, objv[8], &virtual) ) {
- Tcl_ResetResult(interp);
- virtual=0;
- }
- }
- x0 = roundCoord(x0*p->rXZoom);
- y0 = roundCoord(y0*p->rYZoom);
- x1 = roundCoord(x1*p->rXZoom);
- y1 = roundCoord(y1*p->rYZoom);
- if( findSegment(p, id) ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[6],0), " already exists", 0);
- return TCL_ERROR;
- }
- if( floatCompare(x0,x1)==0 && floatCompare(y0,y1)==0 ){
- /* Tcl_AppendResult(interp, "endpoints must be distinct", 0); */
- /* return TCL_ERROR; */
- return TCL_OK; /* Not an error. Just a no-op. */
- }
- clearComptBoxCache(p);
- pSeg = (Segment *)Odie_Alloc( sizeof(*pSeg) );
- if( pSeg==0 ) return TCL_ERROR;
- pSeg->id = id;
- pSeg->idLC = idLC;
- pSeg->idRC = idRC;
- pSeg->from[X_IDX] = x0;
- pSeg->from[Y_IDX] = y0;
- pSeg->to[X_IDX] = x1;
- pSeg->to[Y_IDX] = y1;
- pSeg->isBoundary=virtual;
- LinkInit(pSeg->pAll, pSeg);
- LinkInit(pSeg->pSet, pSeg);
- LinkInit(pSeg->pHash, pSeg);
- LinkInit(pSeg->pFrom, pSeg);
- LinkInit(pSeg->pTo, pSeg);
- LinkInsert(&p->pAll, &pSeg->pAll);
- h = hashInt(id);
- LinkInsert(&p->hashId[h], &pSeg->pHash);
- h = hashCoord(pSeg->from[X_IDX], pSeg->from[Y_IDX]);
- LinkInsert(&p->hashFrom[h], &pSeg->pFrom);
- h = hashCoord(pSeg->to[X_IDX], pSeg->to[Y_IDX]);
- LinkInsert(&p->hashTo[h], &pSeg->pTo);
- return TCL_OK;
- }
- /* OO Method Wallset primary */
- static int OOMethod_Wallset_primary(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET primary X Y
- ** title: Return the primary segment of the compartment enclosing X,Y
- **
- ** The primary segment is the segment with the smallest ID. If the
- ** same segment occurs twice on the list (in other words, if the
- ** same compartment is on both sides of a wall), then the right side
- ** (as measured facing the direction of travel from x0,y0 -> x1,y1)
- ** is used.
- */
- Wallset *p = GETWALLSET(thisObject);
- Boundary aBound[MX_BOUND];
- int nBound;
- double x, y;
- int i, sideSmallest;
- int idSmallest;
- Tcl_Obj *pResult;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X Y");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y) ) return TCL_ERROR;
- nBound = findBoundary(p, x*p->rXZoom, y*p->rYZoom, MX_BOUND, aBound);
- if( nBound>0 && nBound<MX_BOUND ){
- idSmallest = aBound[0].pSeg->id;
- sideSmallest = aBound[0].backwards;
- for(i=1; i<nBound; i++){
- if( aBound[i].pSeg->id>idSmallest ) continue;
- if( aBound[i].pSeg->id<idSmallest || !sideSmallest ){
- idSmallest = aBound[i].pSeg->id;
- sideSmallest = aBound[i].backwards;
- }
- }
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(idSmallest));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(sideSmallest));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Wallset intersect */
- static int OOMethod_Wallset_intersect(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET intersect X0 Y0 X1 Y1
- ** title: Find the intersection of X0,Y0->X1,Y1 with a segment
- **
- ** Scan all segments in the wallset looking for one that intersects with
- ** a line from X0,Y0 to X1,Y1. If the intersection occurs at x0,y0, it
- ** is ignored, but intersections at x1,y1 count. If no such intersection
- ** exists, return the empty string. If there are one or more intersections,
- ** return the ID of the segment and the X and Y coordinates of the nearest
- ** intersection to X0,Y0.
- */
- Wallset *p = GETWALLSET(thisObject);
- double x0,y0,x1,y1;
- double adx, ady;
- Link *pI;
- int id=-1;
- double nx, ny;
- double mindist2 = -1.0;
- if( objc!=6 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X0 Y0 X1 Y1");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &x1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &y1) ) return TCL_ERROR;
- nx = x0 = roundCoord(x0*p->rXZoom);
- ny = y0 = roundCoord(y0*p->rYZoom);
- x1 = roundCoord(x1*p->rXZoom);
- y1 = roundCoord(y1*p->rYZoom);
- adx = x1-x0;
- ady = y1-y0;
- if( adx==0.0 && ady==0.0 ) return TCL_OK;
- for(pI=p->pAll; pI; pI=pI->pNext){
- double bdx, bdy, denom, num1;
- Segment *pSeg;
- pSeg = pI->pLinkNode;
- bdx = pSeg->to[X_IDX] - pSeg->from[X_IDX];
- bdy = pSeg->to[Y_IDX] - pSeg->from[Y_IDX];
- denom = adx*bdy - ady*bdx;
- num1 = (y0-pSeg->from[Y_IDX])*bdx - (x0-pSeg->from[X_IDX])*bdy;
- if( denom==0.0 ){
- /* The reference line and segment are parallel */
- if( num1==0.0 ){
- /* The reference line and segment are colinear */
- if( Vector2d_SamePoint(x0,y0,pSeg->from[X_IDX],pSeg->from[Y_IDX])
- && adx*bdx<=0.0 && ady*bdy<=0.0 ){
- continue;
- }
- if( Vector2d_SamePoint(x0,y0,pSeg->to[X_IDX],pSeg->to[Y_IDX])
- && adx*bdx>=0.0 && ady*bdy>=0.0 ){
- continue;
- }
- if( between(pSeg->from[Y_IDX],y0,y1) && between(pSeg->from[X_IDX],x0,x1) ){
- double dx, dy, dist2;
- dx = pSeg->from[X_IDX] - x0;
- dy = pSeg->from[Y_IDX] - y0;
- dist2 = dx*dx + dy*dy;
- if( mindist2<0 || mindist2>dist2 ){
- mindist2 = dist2;
- nx = pSeg->from[X_IDX];
- ny = pSeg->from[Y_IDX];
- id = pSeg->id;
- }
- }
- if( between(pSeg->to[Y_IDX],y0,y1) && between(pSeg->to[X_IDX],x0,x1) ){
- double dx, dy, dist2;
- dx = pSeg->to[X_IDX] - x0;
- dy = pSeg->to[Y_IDX] - y0;
- dist2 = dx*dx + dy*dy;
- if( mindist2<0 || mindist2>dist2 ){
- mindist2 = dist2;
- nx = pSeg->to[X_IDX];
- ny = pSeg->to[Y_IDX];
- id = pSeg->id;
- }
- }
- if( between(y0,pSeg->from[Y_IDX],pSeg->to[Y_IDX]) && between(x0,pSeg->from[X_IDX],pSeg->to[X_IDX]) ){
- if( mindist2<0 || mindist2>0.0 ){
- mindist2 = 0.0;
- nx = x0;
- ny = y0;
- id = pSeg->id;
- }
- }
- }
- }else{
- /* The reference line and segment are not parallel */
- double r, s;
- r = num1/denom;
- s = ((y0-pSeg->from[Y_IDX])*adx - (x0-pSeg->from[X_IDX])*ady)/denom;
- if( r>0 && r<=1.0 && s>=0.0 && s<=1.0 ){
- double dx, dy, dist2;
- dx = r*adx;
- dy = r*ady;
- dist2 = dx*dx + dy*dy;
- if( dist2>=OdieGrain && (mindist2<0 || mindist2>dist2) ){
- mindist2 = dist2;
- nx = x0 + dx;
- ny = y0 + dy;
- id = pSeg->id;
- }
- }
- }
- }
- if( mindist2>=0.0 ){
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- nx = roundCoord(nx);
- ny = roundCoord(ny);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(nx/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(ny/p->rYZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(id));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Wallset left */
- static int OOMethod_Wallset_left(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET left ID LC
- ** title: Change the left compartment of a line segment
- */
- Wallset *p = GETWALLSET(thisObject);
- int id, idLC;
- Segment *pSeg;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID LC");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[3], &idLC) ) return TCL_ERROR;
- if( (pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- pSeg->idLC = idLC;
- return TCL_OK;
- }
- /* OO Method Wallset list */
- static int OOMethod_Wallset_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET list
- ** title: Return a list of all wall segment identifiers
- */
- Wallset *p = GETWALLSET(thisObject);
- Link *pLink;
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- for(pLink=p->pAll; pLink; pLink=pLink->pNext){
- Segment *pSeg=pLink->pLinkNode;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset looseends */
- static int OOMethod_Wallset_looseends(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET looseends
- ** title: Return a list of walls that are have unconnected ends
- **
- ** For each unconnected end, the list contains four elements:
- ** 1. The wallid
- ** 2. 0 for the "from" end, "1" for the "to" end
- ** 3. The X coordinate of the loose end
- ** 4. The Y coordinate of the loose end
- */
- Wallset *p = GETWALLSET(thisObject);
- Segment *pSeg;
- Link *pAll, *pList;
- Tcl_Obj *pRes = Tcl_NewObj();
- for(pAll=p->pAll; pAll; pAll=pAll->pNext){
- pSeg = pAll->pLinkNode;
- pList = segmentsAtVertex(p, pSeg->from[X_IDX], pSeg->from[Y_IDX]);
- if( LinkCount(pList)==1 ){
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewIntObj(pSeg->id));
- Tcl_ListObjAppendElement(0, pRes, ODIE_INT_ZERO());
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewDoubleObj(pSeg->from[X_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewDoubleObj(pSeg->from[Y_IDX]/p->rYZoom));
- }
- pList = segmentsAtVertex(p, pSeg->to[X_IDX], pSeg->to[Y_IDX]);
- if( LinkCount(pList)==1 ){
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewIntObj(pSeg->id));
- Tcl_ListObjAppendElement(0, pRes, ODIE_INT_ONE());
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewDoubleObj(pSeg->to[X_IDX]/p->rXZoom));
- Tcl_ListObjAppendElement(0, pRes, Tcl_NewDoubleObj(pSeg->to[Y_IDX]/p->rYZoom));
- }
- }
- Tcl_SetObjResult(interp, pRes);
- return TCL_OK;
- }
- /* OO Method Wallset nearest */
- static int OOMethod_Wallset_nearest(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET nearest vertex|point X Y
- ** title: Find the nearest vertex or point to a point in the plan
- */
- Wallset *p = GETWALLSET(thisObject);
- int type;
- double x, y, near_x, near_y;
- static const char *NEAR_strs[] = { "point", "vertex", 0 };
- enum NEAR_enum { NEAR_POINT, NEAR_VERTEX, };
- Link *pLink;
- Tcl_Obj *pResult;
- double dx, dy, dist;
- if( objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "point|vertex X Y");
- return TCL_ERROR;
- }
- if( Tcl_GetIndexFromObj(interp, objv[2], NEAR_strs, "option", 0, &type) ){
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[3], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &y) ) return TCL_ERROR;
- x *= p->rXZoom;
- y *= p->rYZoom;
- ignoreNone(p);
- if( type==NEAR_POINT ){
- pLink = nearestPoint(p, x, y, &near_x, &near_y);
- }else if( type==NEAR_VERTEX ){
- pLink = nearestVertex(p, x, y, &near_x, &near_y);
- }else{
- /* Cannot happen */ return TCL_ERROR;
- }
- if( pLink==0 ) return TCL_OK; /* There are not segments in the wallset */
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(near_x/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(near_y/p->rYZoom));
- dx = x - near_x;
- dy = y - near_y;
- dist = sqrt(dx*dx + dy*dy);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(dist/p->rXZoom));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewObj());
- while( pLink ){
- Segment *pSeg=pLink->pLinkNode;
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- pLink = pLink->pNext;
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset nextcwwall */
- static int OOMethod_Wallset_nextcwwall(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET nextcwwall X0 Y0 X1 Y1
- ** title: Find a wall on X1,Y1 clockwise from X0,Y0->X1,Y1
- */
- Wallset *p = GETWALLSET(thisObject);
- int isBack;
- Segment *pSeg;
- double x0, y0, x1, y1;
- int rc;
- if( objc!=6 ){
- Tcl_WrongNumArgs(interp, 2, objv, "X0 Y0 X1 Y1");
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[2], &x0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &y0) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &x1) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &y1) ) return TCL_ERROR;
- x0 = roundCoord(x0*p->rXZoom);
- y0 = roundCoord(y0*p->rYZoom);
- x1 = roundCoord(x1*p->rXZoom);
- y1 = roundCoord(y1*p->rYZoom);
- rc = nextCwSegment(p, x0, y0, x1, y1, &pSeg, &isBack);
- if( rc==0 ){
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pSeg->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(isBack));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method Wallset right */
- static int OOMethod_Wallset_right(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET right ID RC
- ** title: Change the right compartment of a line segment
- */
- Wallset *p = GETWALLSET(thisObject);
- int id, idRC;
- Segment *pSeg;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID RC");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if( Tcl_GetIntFromObj(interp, objv[3], &idRC) ) return TCL_ERROR;
- if( (pSeg = findSegment(p, id))==0 ){
- Tcl_AppendResult(interp, "segment ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- pSeg->idRC = idRC;
- return TCL_OK;
- }
- /* OO Method Wallset selfcheck */
- static int OOMethod_Wallset_selfcheck(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET selfcheck
- ** title: Verify the integrity of internal data structures
- */
- Wallset *p = GETWALLSET(thisObject);
- return selfCheck(interp, p);
- }
- /* OO Method Wallset zoom */
- static int OOMethod_Wallset_zoom(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclmethod: WALLSET zoom ?ZOOM?
- ** title: Query or change the zoom factor.
- */
- Wallset *p = GETWALLSET(thisObject);
- Tcl_Obj *pResult;
- if( objc!=2 && objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?ZOOM?");
- return TCL_ERROR;
- }
- if( objc==3 ){
- double r;
- if( Tcl_GetDoubleFromObj(interp, objv[2], &r) ) return TCL_ERROR;
- if( r==0.0 ){
- Tcl_AppendResult(interp, "zoom must be non-zero", 0);
- return TCL_ERROR;
- }
- p->rYZoom = r;
- p->rXZoom = fabs(r);
- }
- pResult = Tcl_NewDoubleObj(p->rYZoom);
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method Wallset constructor */
- static int OOMethod_Wallset_constructor(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclcmd: wallset WALLSET
- ** title: Create a new wallset object
- ** This routine runs when the "wallset" command is invoked to create a
- ** new wallset.
- */
- Wallset *p;
- p = (Wallset *)Odie_Alloc( sizeof(*p) );
- p->rXZoom = 100.0;
- p->rYZoom = -100.0;
- Tcl_ObjectSetMetadata(thisObject, &WallsetDataType, (ClientData) p);
- return TCL_OK;
- }
- /* Loader for Wallset */
- static int Wallset_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::wallset" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::wallset" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::wallset", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- /* Attach the constructor to the class */
- Tcl_ClassSetConstructor(interp, curClass, Tcl_NewMethod(interp, curClass, NULL, 1, &OOMethodType_Wallset_constructor, NULL));
- nameObj=Tcl_NewStringObj("atvertex",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_atvertex, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("boundary",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_boundary, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("closure",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_closure, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("closure_polygon",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_closure_polygon, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("closure_check",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_closure_check, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("comptlist",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_comptlist, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("corners",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_corners, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("firstboundary",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_firstboundary, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("foreach",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_foreach, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("info",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_info, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("rawinfo",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_rawinfo, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("insert",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_insert, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("primary",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_primary, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("intersect",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_intersect, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("left",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_left, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("looseends",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_looseends, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nearest",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_nearest, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nextcwwall",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_nextcwwall, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("right",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_right, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("selfcheck",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_selfcheck, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("zoom",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Wallset_zoom, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_create */
- static int OOMethod_PolygonHull_vertex_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullVertex *pVertex;
- VectorXYZ A;
- int vertexid;
- int argidx;
- argidx=Tcl_ObjectContextSkippedArgs(objectContext);
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID XYZ");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &vertexid) ) return TCL_ERROR;
- if(vertexid>0) {
- pVertex=PolygonHullVertex_ById(pHull,vertexid);
- if(pVertex) {
- Tcl_AppendResult(interp, "vertex id ",
- Tcl_GetStringFromObj(objv[2],0), " already exists", 0);
- return TCL_ERROR;
- }
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],A)) return TCL_ERROR;
- pVertex=PolygonHullVertex_ByCoords(pHull,A);
- if(pVertex) {
- Tcl_AppendResult(interp, "vertex already exists at ",
- Tcl_GetStringFromObj(objv[3],0), 0);
- return TCL_ERROR;
- }
- pVertex=PolygonHullVertex_Create(pHull,vertexid,A);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pVertex->id));
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_coords */
- static int OOMethod_PolygonHull_vertex_coords(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- int vertexid;
- PolygonHullVertex *pVertex;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(NULL,objv[2],&vertexid)) return TCL_ERROR;
- /* Handle vertex by id */
- pVertex=PolygonHullVertex_ById(pHull,vertexid);
- if(!pVertex) {
- Tcl_AppendResult(interp, "vertex id ",
- Tcl_GetStringFromObj(objv[2],0), " does not exist", 0);
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(pVertex->center));
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_delete */
- static int OOMethod_PolygonHull_vertex_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace delete ID
- **
- ** Delete a triangle
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullVertex *pVertex;
- int i;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- /*
- if( pHull->busy ){
- Tcl_AppendResult(interp, "cannot \"delete\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- */
- for(i=2;i<objc;i++) {
- int vertexid;
- if(Tcl_GetIntFromObj(NULL,objv[i],&vertexid)==TCL_OK) {
- /* Handle vertex by id */
- pVertex=PolygonHullVertex_ById(pHull,vertexid);
- } else {
- VectorXYZ A;
- if(Odie_GetVectorXYZFromTclObj(NULL,objv[i],A)) continue;
- pVertex=PolygonHullVertex_ByCoords(pHull,A);
- }
- if(pVertex) {
- PolygonHullVertex_Remove(pVertex);
- readiHashInsert(&pHull->VertexHash, 0, pVertex->id, 0);
- Odie_Free((char *)pVertex);
- }
- }
- PolygonHull_clearSurfaces(pHull);
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_idlist */
- static int OOMethod_PolygonHull_vertex_idlist(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace list
- **
- ** Return a list of all triangles currently defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- Tcl_Obj *pResult;
- HashElem *i;
- pResult = Tcl_NewObj();
- for(i=readiHashFirst(&pHull->VertexHash); i; i=readiHashNext(i)) {
- PolygonHullVertex *p=(PolygonHullVertex *)readiHashData(i);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->id));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_inject */
- static int OOMethod_PolygonHull_vertex_inject(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace inject ID ?
- **
- ** Delete a triangle
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullVertex *pThisVertex;
- int i;
- int vertexid;
- if( objc<4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID FACE ?FACE...?");
- return TCL_ERROR;
- }
- /*
- if( pHull->busy ){
- Tcl_AppendResult(interp, "cannot \"delete\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- */
- if(Tcl_GetIntFromObj(NULL,objv[2],&vertexid)==TCL_OK) {
- /* Handle vertex by id */
- pThisVertex=PolygonHullVertex_ById(pHull,vertexid);
- if(!pThisVertex) {
- Tcl_AppendResult(interp, "vertex ", Tcl_GetStringFromObj(objv[3],0), " does not exist", 0);
- return TCL_ERROR;
- }
- } else {
- VectorXYZ A;
- if(Odie_GetVectorXYZFromTclObj(NULL,objv[2],A)) return TCL_ERROR;
- pThisVertex=PolygonHullVertex_ByCoords(pHull,A);
- if(!pThisVertex) {
- pThisVertex=PolygonHullVertex_Create(pHull,-1,A);
- }
- if(!pThisVertex) {
- /* Can't create a vertex from coords */
- Tcl_AppendResult(interp, "Failed to create vertex ", Tcl_GetStringFromObj(objv[3],0), 0);
- return TCL_ERROR;
- }
- }
- for(i=3;i<objc;i++) {
- int faceid;
- const char *err;
- PolygonHullFace *pFace;
- if( Tcl_GetIntFromObj(interp, objv[i], &faceid) ) return TCL_ERROR;
- pFace = PolygonHullFace_ById(pHull,faceid);
- if(!pFace) {
- Tcl_AppendResult(interp, "face ", Tcl_GetStringFromObj(objv[i],0), " does not exist", 0);
- return TCL_ERROR;
- }
- err=PolygonHullFace_VertexInject(pFace,pThisVertex);
- //printf("INJECT %s\n",err);
- PolygonHullFace_Compute(pFace);
- if(err) {
- Tcl_AppendResult(interp, err, " on face ", Tcl_GetStringFromObj(objv[i],0), err, 0);
- return TCL_ERROR;
- }
- }
- PolygonHull_clearSurfaces(pHull);
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_list */
- static int OOMethod_PolygonHull_vertex_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace list
- **
- ** Return a list of all triangles currently defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- Tcl_Obj *pResult;
- HashElem *i;
- pResult = Tcl_NewObj();
- for(i=readiHashFirst(&pHull->VertexHash); i; i=readiHashNext(i)) {
- PolygonHullVertex *p=(PolygonHullVertex *)readiHashData(i);
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(p->center));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull vertex_at */
- static int OOMethod_PolygonHull_vertex_at(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace list
- **
- ** Return a vertices at x,y,z
- */
- VectorXYZ A;
- int i;
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullVertex *pVertex;
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- for(i=2;i<objc;i++) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],A)) {
- Tcl_DecrRefCount(pResult);
- Tcl_AppendResult(interp, "could not interpret ", Tcl_GetString(objv[i]), 0);
- return TCL_ERROR;
- }
- pVertex=PolygonHullVertex_ByCoords(pHull,A);
- if(pVertex) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pVertex->id));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull face_info */
- static int OOMethod_PolygonHull_face_info(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- int id,i;
- PolygonHullFace *pFace;
- static const char *POLYGONHULLFACE_fields[] = { "id", "nVertex", "wallid", "deckid", "typeid", "is_wall", "is_exterior", "is_virtual", "idLC", "idRC", "center", "normal", "radius", "bbox", 0 };
- enum POLYGONHULLFACE_enum { POLYGONHULLFACE_FIELD_ID, POLYGONHULLFACE_FIELD_NVERTEX, POLYGONHULLFACE_FIELD_WALLID, POLYGONHULLFACE_FIELD_DECKID, POLYGONHULLFACE_FIELD_TYPEID, POLYGONHULLFACE_FIELD_IS_WALL, POLYGONHULLFACE_FIELD_IS_EXTERIOR, POLYGONHULLFACE_FIELD_IS_VIRTUAL, POLYGONHULLFACE_FIELD_IDLC, POLYGONHULLFACE_FIELD_IDRC, POLYGONHULLFACE_FIELD_CENTER, POLYGONHULLFACE_FIELD_NORMAL, POLYGONHULLFACE_FIELD_RADIUS, POLYGONHULLFACE_FIELD_BBOX };
- if(objc<3) {
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field value...?");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &pFace) ) return TCL_ERROR;
- if(!pFace) {
- Tcl_AppendResult(interp, "PolygonHullFace does not exist",0);
- return TCL_ERROR;
- }
- for(i=3;i<objc;i+=2) {
- Tcl_Obj *field,*value;
- int option;
- if((i+1) == objc) break;
- field=objv[i];
- value=objv[i+1];
- if( Tcl_GetIndexFromObj(interp, field, POLYGONHULLFACE_fields, "option", 0, &option) ) return TCL_ERROR;
- switch(option) {
- case POLYGONHULLFACE_FIELD_ID: {
- /* Ignore */
- break; } case POLYGONHULLFACE_FIELD_NVERTEX: {
- /* Ignore */
- break; } case POLYGONHULLFACE_FIELD_WALLID: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing wallid",NULL);
- return TCL_ERROR;
- }
- pFace->wallid=temp;
- break; } case POLYGONHULLFACE_FIELD_DECKID: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing deckid",NULL);
- return TCL_ERROR;
- }
- pFace->deckid=temp;
- break; } case POLYGONHULLFACE_FIELD_TYPEID: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing typeid",NULL);
- return TCL_ERROR;
- }
- pFace->typeid=temp;
- break; } case POLYGONHULLFACE_FIELD_IS_WALL: {
- int temp;
- if(Tcl_GetBooleanFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing is_wall",NULL);
- return TCL_ERROR;
- }
- pFace->is_wall=temp;
- break; } case POLYGONHULLFACE_FIELD_IS_EXTERIOR: {
- int temp;
- if(Tcl_GetBooleanFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing is_exterior",NULL);
- return TCL_ERROR;
- }
- pFace->is_exterior=temp;
- break; } case POLYGONHULLFACE_FIELD_IS_VIRTUAL: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing is_virtual",NULL);
- return TCL_ERROR;
- }
- pFace->is_virtual=temp;
- break; } case POLYGONHULLFACE_FIELD_IDLC: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing idLC",NULL);
- return TCL_ERROR;
- }
- pFace->idLC=temp;
- break; } case POLYGONHULLFACE_FIELD_IDRC: {
- int temp;
- if(Tcl_GetIntFromObj(interp,value,&temp)) {
- Tcl_AppendResult(interp," while processing idLC",NULL);
- return TCL_ERROR;
- }
- pFace->idRC=temp;
- break; } case POLYGONHULLFACE_FIELD_CENTER: {
- /* Ignore */
- break; } case POLYGONHULLFACE_FIELD_NORMAL: {
- /* Ignore */
- break; } case POLYGONHULLFACE_FIELD_RADIUS: {
- /* Ignore */
- break; } case POLYGONHULLFACE_FIELD_BBOX: {
- /* Ignore */
- break; } }
- }
- Tcl_SetObjResult(interp, PolygonHullFace_To_Dict(pFace));
- return TCL_OK;
- }
- /* OO Method PolygonHull face_exists */
- static int OOMethod_PolygonHull_face_exists(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *pFace;
- if(objc<3) {
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field value...?");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &pFace) ) return TCL_ERROR;
- if(!pFace) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull face_active */
- static int OOMethod_PolygonHull_face_active(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace active
- ** PolygonHullFace active all
- ** PolygonHullFace active sphere RADIUS X Y Z
- ** PolygonHullFace active ID ...
- **
- ** This first form returns a list of all active triangles. The
- ** other forms set the active triangle list. The 2nd form sets the
- ** active list to all triangles. This is the default setting. The
- ** 4d form sets the active list to all triangles that intersect a
- ** sphere centered at X,Y,Z with radius RADIUS. The 4th form sets
- ** the active triangles to be just those listed.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- if( objc==2 ){
- Tcl_Obj *pResult = Tcl_NewObj();
- for(p=pHull->pActive; p; p=p->pActive){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->id));
- }
- Tcl_SetObjResult(interp, pResult);
- }else if( objc>=3 && strcmp(Tcl_GetString(objv[2]),"all")==0 ){
- HashElem *i;
- pHull->pActive = 0;
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- p = readiHashData(i);
- p->pActive = pHull->pActive;
- pHull->pActive = p;
- }
- }else if(strcmp(Tcl_GetString(objv[2]),"sphere")==0 ){
- double radius;
- VectorXYZ center;
- HashElem *i;
- if(objc!=5 && objc!=7) {
- Tcl_WrongNumArgs( interp, 2, objv, "sphere RADIUS XYZ\nOR\nsphere RADIUS X Y Z" );
- return TCL_ERROR;
- }
- if( Tcl_GetDoubleFromObj(interp, objv[3], &radius) ) return TCL_ERROR;
- if(objc==5) {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[1],center)) return TCL_ERROR;
- }
- if(objc==7) {
- if( Odie_GetMatrixElementFromObj(interp, objv[4], center, X_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[5], center, Y_IDX) ) return TCL_ERROR;
- if( Odie_GetMatrixElementFromObj(interp, objv[6], center, Z_IDX) ) return TCL_ERROR;
- }
- pHull->pActive = 0;
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- p = readiHashData(i);
- if( VectorXYZ_Distance(center,p->center) - p->radius <= radius ){
- p->pActive = pHull->pActive;
- pHull->pActive = p;
- }
- }
- } else {
- int j;
- HashElem *i;
- pHull->pActive = 0;
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- p = readiHashData(i);
- p->pActive = 0;
- }
- for(j=3; j<objc; j++){
- if( PolygonHull_findFace(interp, pHull, objv[j], &p) ) return TCL_ERROR;
- if( p->pActive ) continue;
- p->pActive = pHull->pActive;
- pHull->pActive = p;
- }
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull face_center */
- static int OOMethod_PolygonHull_face_center(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** PolygonHullFace center ID
- **
- ** The center is really just the average of the three vertices.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &p) ) return TCL_ERROR;
- Tcl_SetObjResult(interp,VectorXYZ_To_TclObj(p->center));
- return TCL_OK;
- }
- /* OO Method PolygonHull face_polygon */
- static int OOMethod_PolygonHull_face_polygon(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace coords ID
- **
- ** Return the coordinates for a triangle. The return is a list of
- ** 3 lists of XYZ floating point numbers one for each of three vertices.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- Odie_FaceXYZ *pPolyOut;
- int i;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &p) ) return TCL_ERROR;
- pPolyOut=Odie_FaceXYZ_Create(p->nVertex);
- for(i=0; i<p->nVertex; i++){
- VectorXYZ_Copy(pPolyOut->vertex_xyz[i],p->aVertex[i]->center);
- }
- Odie_FaceXYZ_Compute(interp,pPolyOut);
- Tcl_SetObjResult(interp, Odie_FaceXYZ_NewTclObj(pPolyOut));
- return TCL_OK;
- }
- /* OO Method PolygonHull face_vertices */
- static int OOMethod_PolygonHull_face_vertices(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace vertices ID
- **
- ** Return the coordinates for a triangle. The return is a list of
- ** 3 lists of XYZ floating point numbers one for each of three vertices.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- Tcl_Obj *pResult;
- int i;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &p) ) return TCL_ERROR;
- pResult = Tcl_NewObj();
- for(i=0; i<p->nVertex; i++){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->aVertex[i]->id));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull face_create */
- static int OOMethod_PolygonHull_face_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace create ID A B C
- **
- ** Create a new 3d triangle. Or if the triangle already exists,
- ** change its coordinates.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *pFace;
- int id;
- int i;
- if( objc<5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID XYZ XYZ XYZ ?XYZ...?");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- if(id>0) {
- pFace=PolygonHullFace_ById(pHull,id);
- if(pFace) {
- Tcl_AppendResult(interp, "face ",
- Tcl_GetStringFromObj(objv[2],0), " already exists", 0);
- return TCL_ERROR;
- }
- if (id>=pHull->FaceNextId) {
- pHull->FaceNextId=id;
- }
- } else {
- pHull->FaceNextId++;
- id=pHull->FaceNextId;
- }
- PolygonHull_clearSurfaces(pHull);
- /* Left off here
- ** Need to develop a tool to pick a vertex by ID or by coordinate
- ** allocate missing vertexes, and link the vertex and face together
- */
- pFace = PolygonHullFace_Create(pHull,id);
- if( pFace==0 ) return TCL_ERROR;
- id=pFace->id;
- for(i=0;i<pFace->nVertex;i++) {
- LinkInit(pFace->pVertex[i], pFace);
- }
- pFace->nVertex=objc-3;
- for(i=0;i<objc-3;i++) {
- int vertexid,idxmode=0;
- VectorXYZ A;
- PolygonHullVertex *pVertex;
- if(Tcl_GetIntFromObj(NULL,objv[i+3],&vertexid)==TCL_OK) {
- /* Handle vertex by id */
- pVertex=PolygonHullVertex_ById(pHull,vertexid);
- idxmode=1;
- } else {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i+3],A)) {
- Tcl_AppendResult(interp, "could not interpret ", Tcl_GetString(objv[i+3]), 0);
- goto failed;
- }
- pVertex=PolygonHullVertex_ByCoords(pHull,A);
- }
- if(!pVertex) {
- if(idxmode) {
- Tcl_AppendResult(interp, "no such vertex", 0);
- goto failed;
- }
- pVertex=PolygonHullVertex_Create(pHull,-1,A);
- if(!pVertex) {
- /* Can't create a vertex from an integer */
- Tcl_AppendResult(interp, "no such vertex", 0);
- goto failed;
- }
- }
- pVertex->pNextVertex=pFace->pNextVertex;
- pFace->pNextVertex=pVertex;
- }
- PolygonHullFace_Compute(pFace);
- Tcl_SetObjResult(interp,Tcl_NewIntObj(pFace->id));
- return TCL_OK;
- failed:
- PolygonHullFace_Remove(pFace);
- Odie_Free((char *)pFace);
- return TCL_ERROR;
- }
- /* OO Method PolygonHull face_delete */
- static int OOMethod_PolygonHull_face_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace delete ID
- **
- ** Delete a triangle
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *pFace;
- int id;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- /*
- if( pHull->busy ){
- Tcl_AppendResult(interp, "cannot \"delete\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- */
- if( Tcl_GetIntFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- pFace = PolygonHullFace_ById(pHull,id);
- if( pFace ){
- PolygonHullFace_Remove(pFace);
- readiHashInsert(&pHull->FaceHash, 0, pFace->id, 0);
- Odie_Free((char *)pFace);
- PolygonHull_clearSurfaces(pHull);
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull face_intersect */
- static int OOMethod_PolygonHull_face_intersect(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace intersect A B ?ID?
- **
- ** Find the point of intersection between triangles and the
- ** line segment between X0,Y0,Z0 and X1,Y1,Z1. If ID is
- ** specified, only that one triangle is checked. If ID is
- ** omitted, then all triangles are checked.
- **
- ** The result is a list which is a multiple of 2 elements in length.
- ** Within each group of 2 elements, the first element is
- ** the ID of the intersecting triangle. The next element is an XYZ vectors
- ** with the coordinates of the point of intersection. The
- ** triangles appear on the least in order of increasing distance
- ** from X0,Y0,Z0.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- VectorXYZ start, end;
- double x;
- Tcl_Obj *pResult;
- if( objc!=4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A B ?ID?");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],start)) return TCL_ERROR;
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],end)) return TCL_ERROR;
- if( objc==5 ){
- if( PolygonHull_findFace(interp, pHull, objv[4], &p) ) return TCL_ERROR;
- x = PolygonHull_intersectLineSegFace(p, start, end, p->intersect);
- if( x<0.0 ){
- p = 0;
- }else{
- p->pNext = 0;
- }
- }else{
- p = PolygonHullFace_findHits(pHull,start, end);
- }
- if( p ){
- pResult = Tcl_NewObj();
- while( p ){
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->id));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(p->intersect));
- p = p->pNext;
- }
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull face_list */
- static int OOMethod_PolygonHull_face_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace list
- **
- ** Return a list of all triangles currently defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- Tcl_Obj *pResult;
- HashElem *i;
- pResult = Tcl_NewObj();
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- PolygonHullFace *pFace=readiHashData(i);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->id));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull face_nearest */
- static int OOMethod_PolygonHull_face_nearest(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace nearest X Y Z ?ID?
- **
- ** Find the triangle that is closest to the point X,Y,Z. Or if
- ** ID is specified, find the point on ID that is closest to X,Y,Z.
- ** Return a list that consists of:
- **
- ** * The ID of the triangle
- ** * The distance from X,Y,Z to the triangle
- ** * The point on the triangle closest to X,Y,Z
- **
- ** The return value is a list of 5 elements. An empty string
- ** is returned if no triangles are defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- VectorXYZ A,nearest;
- double d;
- Tcl_Obj *pResult;
- if( objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "XYZ ?ID?");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],A)) return TCL_ERROR;
- if( objc==3 ){
- p = PolygonHullFace_findClosest(pHull, A, nearest, &d);
- } else {
- if( PolygonHull_findFace(interp, pHull, objv[3], &p) ) return TCL_ERROR;
- d = PolygonHull_closestPointOnFace(p, A, nearest);
- }
- if( p ){
- pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewDoubleObj(d));
- Tcl_ListObjAppendElement(0, pResult, VectorXYZ_To_TclObj(nearest));
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull face_radius */
- static int OOMethod_PolygonHull_face_radius(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace radius ID
- **
- ** Return a radius for the given triangle.
- ** The radius the maximum distance from the center to any vertex.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &p) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(p->radius));
- return TCL_OK;
- }
- /* OO Method PolygonHull face_normal */
- static int OOMethod_PolygonHull_face_normal(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace normal ID
- **
- ** Return a normal vector to the given triangle
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &p) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(p->normal));
- return TCL_OK;
- }
- /* OO Method PolygonHull face_side */
- static int OOMethod_PolygonHull_face_side(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace side ID X Y Z
- **
- ** Determine which side of trangle ID the point X,Y,Z is on and return
- ** postive for the front side, negative for the back side or zero
- ** if the point is on the same plane as the triangle.
- **
- ** The front side of a triangle is determined by the right-hand rule
- ** of thumb.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- VectorXYZ pt;
- PolygonHullFace *p;
- VectorXYZ vec; /* Vector from surface to the point */
- double dp; /* Dot product of vec and norm */
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID XYZ");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[3],pt)) return TCL_ERROR;
- if( PolygonHull_findFace(interp, pHull, objv[2], &p) ) return TCL_ERROR;
- VectorXYZ_Subtract(vec, pt, p->center);
- dp = VectorXYZ_Dot_Product(vec, p->normal);
- if(dp<=0) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull face_volume */
- static int OOMethod_PolygonHull_face_volume(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace normal ID
- **
- ** Return a normal vector to the given triangle
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullFace *pFace;
- if( objc!=3 && objc !=4 && objc !=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?side? ?volumeid?");
- return TCL_ERROR;
- }
- if( PolygonHull_findFace(interp, pHull, objv[2], &pFace) ) return TCL_ERROR;
- if(objc==3) {
- Tcl_Obj *pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->idRC));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->idLC));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc==4) {
- int side;
- if( Tcl_GetBooleanFromObj(interp,objv[3], &side) ) return TCL_ERROR;
- if(side) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pFace->idLC));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pFace->idRC));
- }
- return TCL_OK;
- } else {
- int side;
- PolygonHullVolume *pVolume=NULL;
- int volumeid;
- if( Tcl_GetBooleanFromObj(interp,objv[3], &side) ) return TCL_ERROR;
- if(Tcl_GetIntFromObj(interp,objv[4],&volumeid) ) return TCL_ERROR;
- if(volumeid>0) {
- /* Handle vertex by id */
- pVolume=PolygonHullVolume_ById(pHull,volumeid);
- if(!pVolume) {
- Tcl_AppendResult(interp, "volume id ",
- Tcl_GetStringFromObj(objv[4],0), " does not exist", 0);
- return TCL_ERROR;
- }
- }
- if(side) {
- /* sideLeft */
- pFace->idLC=volumeid;
- } else {
- /* sideRight */
- pFace->idRC=volumeid;
- }
- return TCL_OK;
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull faces_at */
- static int OOMethod_PolygonHull_faces_at(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace list
- **
- ** Return a vertices at x,y,z
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- VectorXYZ A;
- int i;
- Link *pLink;
- PolygonHullVertex *pVertex;
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- for(i=2;i<objc;i++) {
- int vertexid;
- if(Tcl_GetIntFromObj(NULL,objv[i],&vertexid)==TCL_OK) {
- /* Handle vertex by id */
- pVertex=PolygonHullVertex_ById(pHull,vertexid);
- } else {
- if(Odie_GetVectorXYZFromTclObj(interp,objv[i],A)) {
- Tcl_DecrRefCount(pResult);
- Tcl_AppendResult(interp, "could not interpret ", Tcl_GetString(objv[i]), 0);
- return TCL_ERROR;
- }
- pVertex=PolygonHullVertex_ByCoords(pHull,A);
- }
- if(pVertex) {
- for(pLink=pVertex->pHashFace;pLink;pLink=pLink->pNext) {
- PolygonHullFace *pFace=pLink->pLinkNode;
- if(pFace) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->id));
- }
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull face_within */
- static int OOMethod_PolygonHull_face_within(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- VectorXYZ POINT,nearest;
- if( objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "A ?ID?");
- return TCL_ERROR;
- }
- if(Odie_GetVectorXYZFromTclObj(interp,objv[2],POINT)) return TCL_ERROR;
- if( objc==4 ){
- PolygonHullFace *pFace;
- double d;
- if( PolygonHull_findFace(interp, pHull, objv[3], &pFace) ) return TCL_ERROR;
- if(!VectorXYZ_AABB_Within(POINT,pFace->bbox)) {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(0));
- } else {
- d = PolygonHull_closestPointOnFace(pFace, POINT, nearest);
- if(d<=Vector_Tolerance) {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(1));
- } else {
- Tcl_SetObjResult(interp,Tcl_NewIntObj(0));
- }
- }
- } else {
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- HashElem *i;
- double d;
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- PolygonHullFace *pFace=readiHashData(i);
- if(!VectorXYZ_AABB_Within(POINT,pFace->bbox)) continue;
- d = PolygonHull_closestPointOnFace(pFace, POINT, nearest);
- if(d<=Vector_Tolerance) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->id));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- }
- return TCL_OK;
- }
- /* OO Method PolygonHull volume_create */
- static int OOMethod_PolygonHull_volume_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullVolume *pVolume=NULL;
- int volumeid;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Tcl_GetIntFromObj(interp, objv[2], &volumeid) ) return TCL_ERROR;
- if(volumeid>0) {
- pVolume=PolygonHullVolume_ById(pHull,volumeid);
- if(pVolume) {
- Tcl_AppendResult(interp, "volume id ",
- Tcl_GetStringFromObj(objv[2],0), " already exists", 0);
- return TCL_ERROR;
- }
- }
- pVolume=PolygonHullVolume_Create(pHull,volumeid);
- Tcl_SetObjResult(interp, Tcl_NewIntObj(pVolume->id));
- return TCL_OK;
- }
- /* OO Method PolygonHull volume_delete */
- static int OOMethod_PolygonHull_volume_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace delete ID
- **
- ** Delete a triangle
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHullVolume *pVolume=NULL;
- int id;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- /*
- if( pHull->busy ){
- Tcl_AppendResult(interp, "cannot \"delete\" from within a \"foreach\"",0);
- return TCL_ERROR;
- }
- */
- if(Tcl_GetIntFromObj(NULL,objv[2],&id)==TCL_OK) {
- /* Handle vertex by id */
- pVolume=PolygonHullVolume_ById(pHull,id);
- }
- if(pVolume) {
- PolygonHullVolume_Unlink(pVolume);
- Odie_Free((char *)pVolume);
- }
- PolygonHull_clearSurfaces(pHull);
- return TCL_OK;
- }
- /* OO Method PolygonHull volume_list */
- static int OOMethod_PolygonHull_volume_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* volume list
- **
- ** Return a list of all triangles currently defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- Tcl_Obj *pResult;
- HashElem *i;
- pResult = Tcl_NewObj();
- for(i=readiHashFirst(&pHull->VolumeHash); i; i=readiHashNext(i)) {
- PolygonHullVolume *p=(PolygonHullVolume *)readiHashData(i);
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->id));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull volume_faces */
- static int OOMethod_PolygonHull_volume_faces(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* volume list
- **
- ** Return a list of all triangles currently defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- int id;
- PolygonHullVolume *pVolume=NULL;
- Tcl_Obj *pResult;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(NULL,objv[2],&id)==TCL_OK) {
- /* Handle vertex by id */
- pVolume=PolygonHullVolume_ById(pHull,id);
- }
- if(!pVolume) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- HashElem *i;
- pResult = Tcl_NewObj();
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- PolygonHullFace *pFace=readiHashData(i);
- if(pFace->idRC==id) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewBooleanObj(0));
- }
- if(pFace->idLC==id) {
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(pFace->id));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewBooleanObj(1));
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method PolygonHull volume_group */
- static int OOMethod_PolygonHull_volume_group(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* volume list
- **
- ** Return a list of all triangles currently defined.
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- int id;
- PolygonHullVolume *pVolume=NULL;
- Tcl_Obj *pResult;
- pResult = Tcl_NewObj();
- if( objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?groupid?");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(NULL,objv[2],&id)==TCL_OK) {
- /* Handle vertex by id */
- pVolume=PolygonHullVolume_ById(pHull,id);
- }
- if(!pVolume) {
- Tcl_AppendResult(interp,"Volume does not exist",NULL);
- return TCL_ERROR;
- }
- if(objc==4) {
- int groupid;
- if(Tcl_GetIntFromObj(NULL,objv[3],&groupid)) return TCL_ERROR;
- pVolume->groupid=groupid;
- }
- Tcl_SetObjResult(interp,Tcl_NewIntObj(pVolume->groupid));
- return TCL_OK;
- }
- /* OO Method PolygonHull volume_center */
- static int OOMethod_PolygonHull_volume_center(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- int id;
- PolygonHullVolume *pVolume=NULL;
- VectorXYZ center;
- int nFaces=0;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(NULL,objv[2],&id)==TCL_OK) {
- /* Handle vertex by id */
- pVolume=PolygonHullVolume_ById(pHull,id);
- }
- if(!pVolume) {
- Tcl_AppendResult(interp,"Volume does not exist",NULL);
- return TCL_ERROR;
- }
- HashElem *i;
- VectorXYZ_Zero(center);
- for(i=readiHashFirst(&pHull->FaceHash); i; i=readiHashNext(i)) {
- PolygonHullFace *pFace=readiHashData(i);
- if(!pFace) continue;
- nFaces++;
- if(pFace->idRC==id) {
- center[X_IDX]+=pFace->center[X_IDX];
- center[Y_IDX]+=pFace->center[Y_IDX];
- center[Z_IDX]+=pFace->center[Z_IDX];
- }
- if(pFace->idLC==id) {
- center[X_IDX]-=pFace->center[X_IDX];
- center[Y_IDX]-=pFace->center[Y_IDX];
- center[Z_IDX]-=pFace->center[Z_IDX];
- }
- }
- if(nFaces>0) {
- center[X_IDX]/=nFaces;
- center[Y_IDX]/=nFaces;
- center[Z_IDX]/=nFaces;
- }
- Tcl_SetObjResult(interp, VectorXYZ_To_TclObj(center));
- return TCL_OK;
- }
- /* OO Method PolygonHull reset */
- static int OOMethod_PolygonHull_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /* PolygonHullFace reset
- **
- ** Delete all triangles
- */
- PolygonHull *pHull = GETPOLYGONHULL(thisObject);
- PolygonHull_Reset(pHull);
- return TCL_OK;
- }
- /* OO Method PolygonHull PolygonHull_Init */
- static int OOMethod_PolygonHull_PolygonHull_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- /*
- ** tclcmd: wallset WALLSET
- ** title: Create a new wallset object
- ** This routine runs when the "wallset" command is invoked to create a
- ** new wallset.
- */
- PolygonHull *p;
- p = (PolygonHull *)Odie_Alloc( sizeof(PolygonHull) );
- p->FaceNextId=0;
- p->VertexNextId=0;
- p->VolumeNextId=0;
- readiHashInit(&p->VertexHash,READI_HASH_INT,0);
- readiHashInit(&p->VolumeHash,READI_HASH_INT,0);
- readiHashInit(&p->FaceHash,READI_HASH_INT,0);
- Tcl_ObjectSetMetadata(thisObject, &PolygonHullDataType, (ClientData) p);
- return TCL_OK;
- }
- /* Loader for PolygonHull */
- static int PolygonHull_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::polygonhull" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::polygonhull" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::polygonhull", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- nameObj=Tcl_NewStringObj("vertex_create",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_coords",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_coords, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_idlist",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_idlist, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_inject",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_inject, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("vertex_at",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_vertex_at, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_info",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_info, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_exists",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_exists, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_active",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_active, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_center",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_center, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_polygon",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_polygon, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_vertices",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_vertices, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_create",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_intersect",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_intersect, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_nearest",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_nearest, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_radius",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_radius, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_normal",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_normal, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_side",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_side, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_volume",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_volume, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("faces_at",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_faces_at, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("face_within",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_face_within, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("volume_create",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_volume_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("volume_delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_volume_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("volume_list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_volume_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("volume_faces",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_volume_faces, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("volume_group",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_volume_group, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("volume_center",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_volume_center, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("reset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_reset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("PolygonHull_Init",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_PolygonHull_PolygonHull_Init, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* Tcl Proc ::get */
- static int TclCmd_get(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *result;
- if(objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "varname");
- return TCL_ERROR;
- }
- result=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(!result) {
- Tcl_ResetResult(interp);
- result=Odie_LiteralConstantObj(ODIE_STATIC_NULL);
- }
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Tcl Proc ::list_to_int */
- static int TclCmd_list_to_int(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int i;
- Tcl_Obj *resultPtr;
- if(objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "element ?element");
- return TCL_ERROR;
- }
- resultPtr=Tcl_NewObj();
- for(i=1;i<objc;i++) {
- Tcl_ListObjAppendElement(interp,resultPtr,Odie_Obj_To_Int(objv[i]));
- }
- Tcl_SetObjResult(interp,resultPtr);
- return TCL_OK;
- }
- /* Tcl Proc ::ladd */
- static int TclCmd_ladd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** topic:
- ** command: ladd
- ** arglist: variable element ...
- ** title: Add all [emph element] arguments to list stored in [emph variable]
- ** description:
- ** If [emph varname] does not exist, an empty list is created. Only one
- ** instance of [emph element] is added per list. If an element is already
- ** in the list, it is not added.
- */
- Tcl_Obj *varPtr,*listObj,*resultPtr;
- int length;
- Tcl_Obj **data;
- if(objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "varname element ...");
- }
- varPtr=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(!varPtr) {
- Tcl_ResetResult(interp);
- varPtr=Tcl_NewObj();
- }
- /*
- ** Make sure we have well formed list
- */
- if(Tcl_ListObjGetElements(interp,varPtr,&length,&data)!=TCL_OK) {
- return TCL_ERROR;
- }
- listObj=Tcl_NewListObj(length,data);
- if(objc>2) {
- if(Tcl_ListObjReplace(interp,listObj,length,0,(objc-2), (objv+2))) {
- return TCL_ERROR;
- }
- }
- resultPtr=Odie_ListObj_Sort(listObj);
- Tcl_ObjSetVar2(interp,objv[1],NULL,resultPtr,0);
- Tcl_SetObjResult(interp,resultPtr);
- return TCL_OK;
- }
- /* Tcl Proc ::ldelete */
- static int TclCmd_ldelete(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- /*
- ** topic:
- ** command: ldelete
- ** arglist: variable element ...
- ** title: Remove all instances of [emph element] from a list stored in [emph variable]
- ** description:
- ** If [emph varname] does not exist, an empty list is created.
- */
- int listLength, idx;
- Tcl_Obj *resultPtr,*listPtr;
- Tcl_Obj **listObjPtrs;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "variable element ...");
- return TCL_ERROR;
- }
- listPtr=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(!listPtr) {
- Tcl_ResetResult(interp);
- listPtr=Tcl_NewObj();
- } else {
- listPtr=Tcl_DuplicateObj(listPtr);
- }
- if(Tcl_ListObjGetElements(interp, listPtr, &listLength, &listObjPtrs)) {
- return TCL_ERROR;
- }
- resultPtr=Tcl_NewObj();
- for(idx=0;idx<listLength;idx++) {
- int matchIdx=Odie_Lsearch((objc-2),(Tcl_Obj **)(objv+2),listObjPtrs[idx]);
- if(matchIdx < 0) {
- Tcl_ListObjAppendElement(interp,resultPtr,listObjPtrs[idx]);
- }
- }
- Tcl_DecrRefCount(listPtr);
- Tcl_ObjSetVar2(interp,objv[1],NULL,resultPtr,0);
- Tcl_SetObjResult(interp,resultPtr);
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::union */
- static int TclCmd_logicset_union(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *listObj;
- int i;
- if(objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "varname element ...");
- return TCL_ERROR;
- }
- listObj=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(!listObj) {
- Tcl_ResetResult(interp);
- listObj=Tcl_NewObj();
- } else {
- if(Tcl_IsShared(listObj)) {
- listObj=Tcl_DuplicateObj(listObj);
- }
- }
- for(i=2;i<objc;i++) {
- Logicset_Include(listObj,objv[i]);
- }
- Tcl_ObjSetVar2(interp,objv[1],NULL,listObj,0);
- Tcl_SetObjResult(interp,listObj);
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::create */
- static int TclCmd_logicset_create(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *stringObj;
- Tcl_DString parse;
- Tcl_DStringInit(&parse);
- if(objc < 2) {
- Tcl_SetObjResult(interp,Tcl_NewObj());
- return TCL_OK;
- }
- int i;
- for(i=1;i<objc;i++) {
- Tcl_DStringAppendElement(&parse,Tcl_GetString(objv[i]));
- }
- int len=Tcl_DStringLength(&parse);
- char *rawvalue=Tcl_DStringValue(&parse);
- Logicset_Sanitize_List(rawvalue,len);
- stringObj=Tcl_NewStringObj(rawvalue,len);
- Tcl_DStringFree(&parse);
- int listLength;
- Tcl_Obj **listObjPtrs;
- if(Tcl_ListObjGetElements(interp, stringObj, &listLength, &listObjPtrs)) {
- return TCL_ERROR;
- }
- Tcl_Obj *listObj=Tcl_NewObj();
- for(i=0;i<listLength;i++) {
- Logicset_Add(listObj,listObjPtrs[i]);
- }
- Tcl_DecrRefCount(stringObj);
- Tcl_SetObjResult(interp,listObj);
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::contains */
- static int TclCmd_logicset_contains(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int listLength, idx, match=1;
- Tcl_Obj **listObjPtrs;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "varlist element ...");
- return TCL_ERROR;
- }
- if(Tcl_ListObjGetElements(interp, objv[1], &listLength, &listObjPtrs)) {
- return TCL_ERROR;
- }
- for(idx=2;idx<objc && match;idx++) {
- int matchIdx=Odie_Lsearch(listLength,listObjPtrs,objv[idx]);
- if(matchIdx < 0) {
- match=0;
- break;
- }
- }
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(match));
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::empty */
- static int TclCmd_logicset_empty(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int length;
- Tcl_Obj **data;
- if(objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "varlist");
- return TCL_ERROR;
- }
- /*
- ** Make sure we have well formed list
- */
- if(Tcl_ListObjGetElements(interp,objv[1],&length,&data)!=TCL_OK) {
- Tcl_ResetResult(interp);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- if(length) {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(1));
- }
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::expr_and */
- static int TclCmd_logicset_expr_and(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- int match=Logicset_EXPR_AND(objv[1],objv[2]);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(match));
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::expr_or */
- static int TclCmd_logicset_expr_or(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- int match=Logicset_EXPR_OR(objv[1],objv[2]);
- Tcl_SetObjResult(interp,Tcl_NewBooleanObj(match));
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::product_intersect */
- static int TclCmd_logicset_product_intersect(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- Tcl_Obj *product=Logicset_PRODUCT_INTERSECT(objv[1],objv[2]);
- if(product) {
- Tcl_SetObjResult(interp,product);
- } else {
- Tcl_SetObjResult(interp,Tcl_NewObj());
- }
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::product_union */
- static int TclCmd_logicset_product_union(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- Tcl_Obj *product=Logicset_PRODUCT_UNION(objv[1],objv[2]);
- if(product) {
- Tcl_SetObjResult(interp,product);
- } else {
- Tcl_SetObjResult(interp,Tcl_NewObj());
- }
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::product_xor */
- static int TclCmd_logicset_product_xor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- Tcl_Obj *product=Logicset_PRODUCT_XOR(objv[1],objv[2]);
- if(product) {
- Tcl_SetObjResult(interp,product);
- } else {
- Tcl_SetObjResult(interp,Tcl_NewObj());
- }
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::product_missing */
- static int TclCmd_logicset_product_missing(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "A B");
- return TCL_ERROR;
- }
- Tcl_Obj *product=Logicset_PRODUCT_MISSING(objv[1],objv[2]);
- if(product) {
- Tcl_SetObjResult(interp,product);
- } else {
- Tcl_SetObjResult(interp,Tcl_NewObj());
- }
- return TCL_OK;
- }
- /* Tcl Proc ::logicset::remove */
- static int TclCmd_logicset_remove(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int listLength, idx;
- Tcl_Obj *resultPtr,*listPtr;
- Tcl_Obj **listObjPtrs;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "variable element ...");
- return TCL_ERROR;
- }
- listPtr=Tcl_ObjGetVar2(interp,objv[1],NULL,0);
- if(!listPtr) {
- Tcl_ResetResult(interp);
- listPtr=Tcl_NewObj();
- } else {
- listPtr=Tcl_DuplicateObj(listPtr);
- }
- if(Tcl_ListObjGetElements(interp, listPtr, &listLength, &listObjPtrs)) {
- return TCL_ERROR;
- }
- resultPtr=Tcl_NewObj();
- for(idx=0;idx<listLength;idx++) {
- int matchIdx=Odie_Lsearch((objc-2),(Tcl_Obj **)(objv+2),listObjPtrs[idx]);
- if(matchIdx < 0) {
- Logicset_Add(resultPtr,listObjPtrs[idx]);
- }
- }
- Tcl_ObjSetVar2(interp,objv[1],NULL,resultPtr,0);
- Tcl_SetObjResult(interp,resultPtr);
- return TCL_OK;
- }
- /* Tcl Proc ::literal */
- static int TclCmd_literal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- char *newName;
- Tcl_Obj *result;
- if(objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "string");
- return TCL_ERROR;
- }
- newName=Tcl_GetString(objv[1]);
- result=Odie_LiteralStringObj(newName);
- if (!result) return TCL_ERROR;
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Tcl Proc ::literal_dump */
- static int TclCmd_literal_dump(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_HashSearch searchPtr;
- Tcl_HashEntry *i;
- Tcl_Obj *result;
- result=Tcl_NewObj();
- for(i=Tcl_FirstHashEntry(&OdieLiteralStringTable,&searchPtr); i ; i = Tcl_NextHashEntry(&searchPtr)) {
- Tcl_Obj *p = (Tcl_Obj *)Tcl_GetHashValue(i);
- Tcl_ListObjAppendElement(interp,result,p);
- }
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Tcl Proc ::literal_stats */
- static int TclCmd_literal_stats(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_Obj *result;
- result=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("literal count:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieObjString));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("hash table count:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieHashTable));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("hash table created:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieHashTableCreated));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("hash table deleted:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieHashTableDeleted));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec count:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecCount));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec created:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecCreated));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec deleted:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecDeleted));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec shared:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecShared));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec null:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecNull));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec recycled:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecRecycled));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec modified:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecModified));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewStringObj("dict spec accessed:",-1));
- Tcl_ListObjAppendElement(interp,result,Tcl_NewIntObj(nOdieDictSpecAccessed));
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Tcl Proc ::constant_string */
- static int TclCmd_constant_string(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- char *newName;
- Tcl_Obj *result;
- if(objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "string");
- return TCL_ERROR;
- }
- newName=Tcl_GetString(objv[1]);
- result=Odie_LiteralStringObj(newName);
- if (!result) return TCL_ERROR;
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Tcl Proc ::location::grid_square */
- static int TclCmd_location_grid_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double grid;
- double x;
- double y;
- Tcl_Obj *pResult;
- if( objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize x y");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&y)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*round(x/grid)));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*round(y/grid)));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::location::gridhash_square */
- static int TclCmd_location_gridhash_square(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x, y;
- int grid,deckid;
- Tcl_WideInt result;
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize deck x y");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetIntFromObj(interp,objv[2],&deckid)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&y)) return TCL_ERROR;
- result=irm_squaregrid_hash(grid,deckid,(int)x,(int)y);
- Tcl_SetObjResult(interp,Tcl_NewWideIntObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::location::location_gridhash */
- static int TclCmd_location_location_gridhash(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Irm_Location dest;
- int grid;
- Tcl_WideInt hash;
- Tcl_Obj *pResult;
- if( objc != 3 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize hash");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetWideIntFromObj(interp,objv[2],&hash)) return TCL_ERROR;
- irm_gridhash_location(&dest,hash,grid);
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Odie_LiteralIntObj(dest.deckid));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(dest.x));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(dest.y));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::location::grid_hex */
- static int TclCmd_location_grid_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double grid, x, y;
- int gx,gy;
- Tcl_Obj *pResult;
- if( objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize x y");
- return TCL_ERROR;
- }
- if(Tcl_GetDoubleFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[2],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&y)) return TCL_ERROR;
- pResult=Tcl_NewObj();
- gy=(int)round(y/grid);
- if(gy%2==1){
- gx=(int)round((x-grid/2)/grid);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*gx+grid/2));
- } else {
- gx=(int)round(x/grid);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*gx));
- }
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewDoubleObj(grid*gy));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::location::gridhash_hex */
- static int TclCmd_location_gridhash_hex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- double x, y;
- int grid,deckid;
- Tcl_WideInt result;
- if( objc != 5 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridsize deck x y");
- return TCL_ERROR;
- }
- if(Tcl_GetIntFromObj(interp,objv[1],&grid)) return TCL_ERROR;
- if(Tcl_GetIntFromObj(interp,objv[2],&deckid)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[3],&x)) return TCL_ERROR;
- if(Tcl_GetDoubleFromObj(interp,objv[4],&y)) return TCL_ERROR;
- result=irm_hexgrid_hash(grid,deckid,(int)x,(int)y);
- Tcl_SetObjResult(interp,Tcl_NewWideIntObj(result));
- return TCL_OK;
- }
- /* Tcl Proc ::location::gridhash_adjacent */
- static int TclCmd_location_gridhash_adjacent(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- Tcl_WideInt hash;
- Tcl_Obj *pResult;
- int x,y;
- int gx,gy,deckid,isHex;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "gridhash");
- return TCL_ERROR;
- }
- if(Tcl_GetWideIntFromObj(interp,objv[1],&hash)) return TCL_ERROR;
- /* decompose */
- irm_gridhash_decompose(hash,&isHex,&deckid,&gx,&gy);
- pResult=Tcl_NewObj();
- if(isHex) {
- /* Each hexagonal tile has 6 adjacent tiles
- ** ##
- ** # #
- ** ##
- */
- Tcl_WideInt tile;
- tile=irm_gridhash_compose(1,deckid,gx+1,gy);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- tile=irm_gridhash_compose(1,deckid,gx,gy+1);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- tile=irm_gridhash_compose(1,deckid,gx-1,gy+1);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- tile=irm_gridhash_compose(1,deckid,gx-1,gy);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- tile=irm_gridhash_compose(1,deckid,gx-1,gy-1);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- tile=irm_gridhash_compose(1,deckid,gx,gy-1);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- } else {
- /* Each square tile has 9 adjacent tiles
- ** ###
- ** # #
- ** ###
- */
- for(x=-1;x<=1;x++) {
- for(y=-1;y<=1;y++) {
- Tcl_WideInt tile;
- if(x==0 && y==0) continue;
- tile=irm_gridhash_compose(0,deckid,gx+x,gy+y);
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewWideIntObj(tile));
- }
- }
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::location::object */
- static int TclCmd_location_object(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int deckid;
- double x,y;
- Tcl_Obj *pResult;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "node");
- return TCL_ERROR;
- }
- if(Location_FromTclObj(interp,objv[1],&deckid,&x,&y)) {
- return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Odie_LiteralIntObj(deckid));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(x));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(y));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::location::midpoint */
- static int TclCmd_location_midpoint(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int deckid;
- double x,y,z;
- Tcl_Obj *pResult;
- if( objc != 2 ){
- Tcl_WrongNumArgs(interp, 1, objv, "node");
- return TCL_ERROR;
- }
- if(Location_Base_FromTclObj(interp,objv[1],&deckid,&x,&y,&z)) {
- return TCL_ERROR;
- }
- pResult=Tcl_NewObj();
- Tcl_ListObjAppendElement(interp,pResult,Odie_LiteralIntObj(deckid));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(x));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(y));
- Tcl_ListObjAppendElement(interp,pResult,Tcl_NewIntObj(z));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* Tcl Proc ::location::match */
- static int TclCmd_location_match(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
- int a_deckid;
- double a_x,a_y;
- int b_deckid;
- double b_x,b_y;
- double tolerance=1.0;
- int match=1;
- if( objc != 3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 1, objv, "A B ?tolerance?");
- return TCL_ERROR;
- }
- if(Location_FromTclObj(interp,objv[1],&a_deckid,&a_x,&a_y)) {
- return TCL_ERROR;
- }
- if(Location_FromTclObj(interp,objv[2],&b_deckid,&b_x,&b_y)) {
- return TCL_ERROR;
- }
- if(objc==4) {
- if(Tcl_GetDoubleFromObj(interp,objv[3],&tolerance)) {
- return TCL_ERROR;
- }
- }
- if(a_deckid!=b_deckid) {
- match=0;
- } else {
- double dx,dy;
- dx=fabs(b_x-a_x);
- if(dx > tolerance) {
- match=0;
- } else {
- dy=fabs(b_y-a_y);
- if(dy > tolerance) {
- match=0;
- }
- }
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match));
- return TCL_OK;
- }
- /* OO Method Simulator C_Init */
- static int OOMethod_Simulator_C_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Simulator *p;
- p = (Simulator *)Odie_Alloc( sizeof(*p) );
- Tcl_InitHashTable(&p->EntityIdSet, TCL_STRING_KEYS);
- Tcl_InitHashTable(&p->SimTypeIdSet, TCL_ONE_WORD_KEYS);
- Tcl_ObjectSetMetadata(thisObject, &SimulatorDataType, (ClientData) p);
- return TCL_OK;
- }
- /* Loader for Simulator */
- static int Simulator_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::simulator" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::simulator" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::simulator", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- nameObj=Tcl_NewStringObj("C_Init",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_Simulator_C_Init, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* OO Method OOEntity C_Init */
- static int OOMethod_OOEntity_C_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Simulator *p;
- Tcl_Object masterObject;
- if(objc!=3) {
- Tcl_WrongNumArgs(interp, 2, objv, "SIMULATOR_OBJECT");
- return TCL_ERROR;
- }
- masterObject=Tcl_GetObjectFromObj(interp,objv[2]);
- if(masterObject==NULL) {
- return TCL_ERROR;
- }
- p=GETSIMULATOR(masterObject);
- Tcl_ObjectSetMetadata(thisObject, &SimulatorDataType, (ClientData) p);
- return TCL_OK;
- }
- /* OO Method OOEntity create */
- static int OOMethod_OOEntity_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- Entity *pType=NULL;
- const char *zName;
- if( objc!=3 && objc!=4 && objc != 5){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME ?typeid?");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- zName = Tcl_GetString(objv[2]);
- p=Entity_ByName(zName,1);
- if(objc > 4) {
- if( SimType_FromTclObj(interp, objv[3], &pType) ) return TCL_ERROR;
- p->pType=pType;
- }
- return TCL_OK;
- }
- /* OO Method OOEntity attach_to */
- static int OOMethod_OOEntity_attach_to(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *pNat;
- if( objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID NODEID");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &pNat) ) return TCL_ERROR;
- #ifdef build_IRM
- if(objc==3) {
- Tcl_Obj *pResult=NULL;
- if(pNat->attached_to) {
- switch (pNat->attached_type) {
- case CSTRUCT_crew: {
- pResult=Crew_PublicId(pNat->attached_to);
- break;
- }
- case CSTRUCT_entity: {
- pResult=Entity_Identify(pNat->attached_to);
- break;
- }
- case CSTRUCT_portal: {
- pResult=Portal_PublicId(pNat->attached_to);
- break;
- }
- case CSTRUCT_simnode: {
- pResult=SimNode_PublicId(pNat->attached_to);
- break;
- }
- }
- }
- if(pResult) {
- Tcl_SetObjResult(interp,pResult);
- }
- return TCL_OK;
- }
- #endif
- return Entity_StructAttachLocation(interp,pNat,objv[2]);
- }
- /* OO Method OOEntity compartment */
- static int OOMethod_OOEntity_compartment(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- if( objc!=3 && objc!=4){
- Tcl_WrongNumArgs(interp, 2, objv, "NODEID ?COMPTID?");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- /* Compartments report themselves */
- if(p->public_class=='c') {
- Tcl_SetObjResult(interp,Entity_Identify(p));
- return TCL_OK;
- }
- if(objc==3) {
- p->comptPtr=Entity_IdentifyCompartment(objv[3]);
- }
- #ifdef build_IRM
- if(!p->comptPtr) {
- Irm_Location temp;
- int cid=0;
- Entity_StructLocation(&temp,p);
- cid=Compartment_At_Location(&temp);
- p->comptPtr=Entity_ById('c',cid,0);
- }
- #endif
- if(p->comptPtr) {
- Tcl_SetObjResult(interp,Entity_Identify(p->comptPtr));
- } else {
- Tcl_SetObjResult(interp,Odie_LiteralIntObj(0));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity comptid */
- static int OOMethod_OOEntity_comptid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- if( objc!=3 && objc!=4){
- Tcl_WrongNumArgs(interp, 2, objv, "NODEID ?COMPTID?");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(objc==4) {
- p->comptPtr=Entity_IdentifyCompartment(objv[3]);
- }
- if(p->comptPtr) {
- Tcl_SetObjResult(interp,Entity_Identify(p->comptPtr));
- } else {
- Tcl_SetObjResult(interp,Odie_LiteralIntObj(0));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity count */
- static int OOMethod_OOEntity_count(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- int domatch=0;
- int result=0;
- CurrentSim=GETSIMULATOR(thisObject);
- if(objc==3) {
- domatch=1;
- if(Entity_BuildMatch(interp,objv[2],matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- for(i=Entity_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(domatch) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- result++;
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
- return TCL_OK;
- }
- /* OO Method OOEntity deckid */
- static int OOMethod_OOEntity_deckid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *pNat;
- Irm_Location temp;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &pNat) ) return TCL_ERROR;
- Entity_StructLocation(&temp,pNat);
- Tcl_SetObjResult(interp,Odie_LiteralIntObj(temp.deckid));
- return TCL_OK;
- }
- /* OO Method OOEntity delete */
- static int OOMethod_OOEntity_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NAME");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- if(p) {
- Entity_Unlink(p);
- Entity_Delete(p);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity drawn_reset */
- static int OOMethod_OOEntity_drawn_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- CurrentSim=GETSIMULATOR(thisObject);
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_drawn=0;
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity exists */
- static int OOMethod_OOEntity_exists(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity for */
- static int OOMethod_OOEntity_for(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- int searchresult=TCL_OK;
- Tcl_Obj **varv;
- int varc;
- Tcl_Obj *keyvar;
- Tcl_Obj *infovar=NULL;
- Tcl_Obj *body,*matchvalues=NULL;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- if( objc != 4 && objc != 5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "{keyvar ?valvar?} ?matchlist? body");
- return TCL_ERROR;
- }
- if (Tcl_ListObjGetElements(interp, objv[2], &varc, &varv) != TCL_OK) {
- return TCL_ERROR;
- }
- if(varc==0) {
- keyvar=Odie_LiteralStringObj("id");
- } else {
- keyvar=varv[0];
- }
- Tcl_IncrRefCount(keyvar);
- if(varc>1) {
- infovar=varv[1];
- Tcl_IncrRefCount(infovar);
- } else {
- infovar=NULL;
- }
- if(objc==4) {
- body=objv[3];
- } else {
- matchvalues=objv[3];
- body=objv[4];
- }
- if(Entity_BuildMatch(interp,matchvalues,matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- searchresult=TCL_OK;
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=Entity_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(matchvalues) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- Tcl_ObjSetVar2(interp, keyvar, (Tcl_Obj *)NULL, Entity_Identify(p), 0);
- if(infovar) {
- Tcl_ObjSetVar2(interp, infovar, (Tcl_Obj *)NULL, Entity_StructToDict(interp,p,1), 0);
- }
- searchresult=Tcl_EvalObjEx(interp,body,0);
- if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
- break;
- }
- }
- Tcl_DecrRefCount(keyvar);
- if(infovar) {
- Tcl_DecrRefCount(infovar);
- }
- Odie_Free((char *)searchPtr);
- return searchresult;
- }
- /* OO Method OOEntity foreach */
- static int OOMethod_OOEntity_foreach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- int searchresult=TCL_OK;
- Tcl_Obj *body,*matchvalues=NULL;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- if( objc != 3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "?matchlist? body");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if(objc==3) {
- body=objv[2];
- } else {
- matchvalues=objv[2];
- body=objv[3];
- }
- if(Entity_BuildMatch(interp,matchvalues,matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=Entity_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(matchvalues) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- searchresult=Entity_nodeeval(interp,p,body,0);
- if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
- Odie_Free((char *)searchPtr);
- return searchresult;
- }
- }
- Odie_Free((char *)searchPtr);
- return TCL_OK;
- }
- /* OO Method OOEntity groupid */
- static int OOMethod_OOEntity_groupid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- Roid groupid=0;
- if( objc!=3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?groupid?");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_ResetResult(interp);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- if(objc==4) {
- if(Irm_GetRoidFromObj(interp,objv[2],&groupid)) {
- return TCL_ERROR;
- }
- Entity_StructSetGroup(p,groupid);
- }
- groupid=Entity_StructGetGroup(p);
- if(groupid>0) {
- Tcl_SetObjResult(interp, Irm_NewRoidObj(groupid));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity groups_recalculate */
- static int OOMethod_OOEntity_groups_recalculate(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- CurrentSim=GETSIMULATOR(thisObject);
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->gType=NULL;
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity hidden_inherit */
- static int OOMethod_OOEntity_hidden_inherit(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- CurrentSim=GETSIMULATOR(thisObject);
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(p->pType) {
- if(p->pType->public_hidden) {
- p->public_hidden=1;
- } else {
- p->public_hidden=0;
- }
- }
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity list */
- static int OOMethod_OOEntity_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- int domatch=0;
- CurrentSim=GETSIMULATOR(thisObject);
- if(objc==3) {
- domatch=1;
- if(Entity_BuildMatch(interp,objv[2],matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- for(i=Entity_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(domatch) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- Tcl_ListObjAppendElement(interp, pResult, Entity_Identify(p));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method OOEntity location */
- static int OOMethod_OOEntity_location(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *p;
- if( objc!=3 && objc!=4 && objc!=6 && objc!=7){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?D X Y ?ZOFF??");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if( objc==3 ){
- Tcl_Obj *pResult = Tcl_NewObj();
- Irm_Location temp;
- Entity_StructLocation(&temp,p);
- Tcl_ListObjAppendElement(0, pResult, Odie_LiteralIntObj(temp.deckid));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(temp.x));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(temp.y));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(temp.zoff));
- Tcl_SetObjResult(interp, pResult);
- } else if( objc==4 ) {
- double x, y;
- int did;
- if( Location_FromTclObj(interp,objv[3],&did,&x,&y) ) {
- return TCL_ERROR;
- }
- p->x = (long)x;
- p->y = (long)y;
- p->deckid = did;
- p->zoff=0;
- Entity_Node_ApplyLocation(p);
- } else {
- double x, y, zoff;
- int did;
- if( Tcl_GetIntFromObj(interp, objv[3], &did) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &x) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[5], &y) ) return TCL_ERROR;
- p->attached_to=NULL;
- p->attached_type=0;
- p->x = (long)x;
- p->y = (long)y;
- p->deckid = did;
- if(objc==7) {
- if( Tcl_GetDoubleFromObj(interp, objv[6], &zoff) ) {
- Tcl_ResetResult(interp);
- zoff=0;
- }
- p->zoff=(int)zoff;
- }
- Entity_Node_ApplyLocation(p);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity midpoint */
- static int OOMethod_OOEntity_midpoint(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Irm_Location temp;
- int height;
- if( objc!=3){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- Tcl_Obj *pResult = Tcl_NewObj();
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- Entity_StructLocation(&temp,p);
- height=Entity_StructSizeZ(p);
- Tcl_ListObjAppendElement(0, pResult, Odie_LiteralIntObj(temp.deckid));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(temp.x));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(temp.y));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(temp.zoff+height/2));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method OOEntity nodeget */
- static int OOMethod_OOEntity_nodeget(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field?");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==4) {
- Tcl_Obj *result;
- int offset=-1,err,type;
- err=Entity_StructValueOffset(interp, objv[3], &offset,&type);
- if(err == TCL_OK ) {
- result=Entity_StructGet(p,offset);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Pull the value from extended dict */
- result=Entity_SpecHashGet(p,objv[3],ODIE_NULL_EMPTY);
- Tcl_SetObjResult(interp,result);
- } else {
- Tcl_SetObjResult(interp,Entity_StructToDict(interp,p,1));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity nodeput */
- static int OOMethod_OOEntity_nodeput(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Tcl_DictSearch search;
- Tcl_Obj *key, *value, *objPtr;
- int done;
- int offset,type,err=TCL_OK;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- if( Entity_StructValueOffset(interp, key, &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,p,offset,value);
- if(err != TCL_OK) {
- break;
- }
- } else {
- Entity_SpecHashPut(p,key,value);
- Tcl_SetObjResult(interp, value);
- }
- }
- Tcl_DictObjDone(&search);
- if(err==TCL_OK) {
- Entity_ApplySettings(p);
- }
- return err;
- }
- /* OO Method OOEntity nodewith */
- static int OOMethod_OOEntity_nodewith(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID body");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- return Entity_nodeeval(interp,p,objv[3],1);
- }
- /* OO Method OOEntity normalize */
- static int OOMethod_OOEntity_normalize(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, Entity_Identify(p));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity orientation */
- static int OOMethod_OOEntity_orientation(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc!=3 && objc!=5 && objc!=6){
- Tcl_WrongNumArgs(interp, 1, objv, "ID ?nx ny nz?");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if( objc>3 ){
- double nx,ny,nz;
- if( Tcl_GetDoubleFromObj(interp, objv[3], &nx) ) return TCL_ERROR;
- if( Tcl_GetDoubleFromObj(interp, objv[4], &ny) ) return TCL_ERROR;
- p->nx =(int)nx;
- p->ny =(int)ny;
- p->nz = 0;
- if(objc==6) {
- if( Tcl_GetDoubleFromObj(interp, objv[4], &nz) ) return TCL_ERROR;
- p->nz =(int)nz;
- }
- }
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->nx));
- Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(p->ny));
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method OOEntity redraw */
- static int OOMethod_OOEntity_redraw(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc!=3 ) {
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(p->public_redraw));
- p->public_redraw=0;
- return TCL_OK;
- }
- /* OO Method OOEntity reset */
- static int OOMethod_OOEntity_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Simulator_Reset(CurrentSim);
- Entity_Module_Free(CurrentSim);
- Entity_Module_Init(CurrentSim);
- Simulator_Init(CurrentSim);
- Tcl_ResetResult(interp);
- return TCL_OK;
- }
- /* OO Method OOEntity setting */
- static int OOMethod_OOEntity_setting(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- int offset,type,rcode;
- /* If given a new value, act like a stylized set */
- Entity *p;
- if( objc!=4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID FIELD ?VALUE?");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc == 5) {
- if( Entity_StructValueOffset(interp, objv[3], &offset, &type) == TCL_OK ) {
- rcode=Entity_StructSet(interp,p,offset,objv[4]);
- return rcode;
- }
- rcode=Entity_SetFromObj(interp,p,objv[3],objv[4]);
- return rcode;
- } else {
- Tcl_Obj *result;
- int offset=-1,err,type;
- err=Entity_StructValueOffset(interp, objv[3], &offset,&type);
- if(err == TCL_OK ) {
- result=Entity_StructGet(p,offset);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Pull the value from extended dict */
- result=Entity_ExportField(p->pType,p->infoDict,Tcl_GetString(objv[3]),ODIE_NULL_ZERO);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- }
- /* OO Method OOEntity spec_get */
- static int OOMethod_OOEntity_spec_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Tcl_Obj *pResult=NULL;
- if( objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field?");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==4) {
- /* Pull the value from extended dict */
- pResult=Entity_SpecHashGet(p,objv[3],ODIE_NULL_EMPTY);
- } else {
- pResult=Entity_GetDict(p->pType,p->infoDict);
- }
- if(pResult) {
- Tcl_SetObjResult(interp,pResult);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity spec_put */
- static int OOMethod_OOEntity_spec_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Tcl_DictSearch search;
- Tcl_Obj *key, *value, *objPtr;
- int done;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- Entity_SpecHashPut(p,key,value);
- Tcl_SetObjResult(interp, value);
- }
- Tcl_DictObjDone(&search);
- return TCL_OK;
- }
- /* OO Method OOEntity spec_replace */
- static int OOMethod_OOEntity_spec_replace(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Tcl_DictSearch search;
- Tcl_Obj *key, *value, *objPtr;
- int done;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- Entity_SpecHashClear(p);
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- Entity_SpecHashPut(p,key,value);
- Tcl_SetObjResult(interp, value);
- }
- Tcl_DictObjDone(&search);
- return TCL_OK;
- }
- /* OO Method OOEntity struct_get */
- static int OOMethod_OOEntity_struct_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field?");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==4) {
- Tcl_Obj *result;
- int offset=-1,err,type;
- err=Entity_StructValueOffset(interp, objv[3], &offset,&type);
- if(err == TCL_OK ) {
- result=Entity_StructGet(p,offset);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp,Entity_StructToDict(interp,p,0));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity struct_put */
- static int OOMethod_OOEntity_struct_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Tcl_DictSearch search;
- int done;
- int offset,type,err=TCL_OK;
- if( objc!=4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==5) {
- if( Entity_StructValueOffset(interp, objv[3], &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,p,offset,objv[4]);
- if(err != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- return TCL_ERROR;
- }
- } else {
- Tcl_Obj *key, *value;
- Tcl_Obj *objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- if( Entity_StructValueOffset(interp, key, &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,p,offset,value);
- if(err != TCL_OK) {
- break;
- }
- } else {
- return TCL_ERROR;
- }
- }
- Tcl_DictObjDone(&search);
- }
- if(err==TCL_OK) {
- Entity_ApplySettings(p);
- }
- return err;
- }
- /* OO Method OOEntity type */
- static int OOMethod_OOEntity_type(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Entity *pType;
- if( objc != 3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NODEID field");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- pType=Entity_StructGetType(p);
- if(!pType) {
- if(objc==3) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- if(objc==3) {
- Tcl_SetObjResult(interp, SimType_Identify(pType));
- }
- if(objc==4) {
- Tcl_Obj *pResult;
- pResult=Entity_ExportField(pType,NULL,Tcl_GetString(objv[3]),ODIE_NULL_EMPTY);
- Tcl_SetObjResult(interp,pResult);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity typeid */
- static int OOMethod_OOEntity_typeid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- Entity *pType;
- if( objc!=3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?typeid?");
- return TCL_ERROR;
- }
- if( Entity_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==4) {
- if( SimType_FromTclObj(interp, objv[3], &pType) ) {
- /* Translate a ZERO length list to null */
- int len;
- if(Tcl_ListObjLength(NULL,objv[3],&len)) {
- return TCL_ERROR;
- }
- if(len) {
- int intval;
- if(Tcl_GetIntFromObj(NULL,objv[3],&intval)==TCL_ERROR) {
- return TCL_ERROR;
- }
- if(intval>0) {
- return TCL_ERROR;
- }
- }
- Tcl_ResetResult(interp);
- pType=NULL;
- }
- Entity_StructSetType(p,pType);
- /* Reset the group pointer so it's recalculated */
- Entity_StructSetGroup(p,-1);
- }
- pType=Entity_StructGetType(p);
- if(pType) {
- Tcl_SetObjResult(interp, SimType_Identify(pType));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- /* OO Method OOEntity visible */
- static int OOMethod_OOEntity_visible(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Entity *p;
- if( objc != 2 && objc!=3 && objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "?ID? ?VALUE?");
- return TCL_ERROR;
- }
- if(objc==2) {
- /*
- ** If zero arguments return a list of all nodes with the
- ** visible flag set
- */
- Tcl_Obj *pResult;
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- i = Entity_First(CurrentSim,&search);
- pResult = Tcl_NewObj();
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(p->public_visible) {
- Tcl_ListObjAppendElement(0, pResult, Entity_Identify(p));
- }
- i = Tcl_NextHashEntry(&search);
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- if(objc==3) {
- /*
- ** With one argument, query the visible flag
- ** of a specific node
- */
- if( Entity_FromTclObj(interp, objv[2], &p) ) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(p->public_visible));
- return TCL_OK;
- }
- /*
- ** With two arguments, set a list of nodes given in
- ** argument 1 to the new status argument 2
- */
- if( objc==4 ){
- int i,n,value;
- Tcl_Obj *element;
- if(Tcl_ListObjLength(interp,objv[2],&n)) return TCL_ERROR;
- if(Tcl_GetBooleanFromObj(interp, objv[3], &value)) return TCL_ERROR;
- for(i=0;i<n;i++) {
- if(Tcl_ListObjIndex(interp, objv[2], i, &element)) return TCL_ERROR;
- if(Entity_FromTclObj(interp, element, &p)) continue;
- p->public_visible=value;
- }
- }
- return TCL_OK;
- }
- /* OO Method OOEntity visible_filter */
- static int OOMethod_OOEntity_visible_filter(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(p->pType) {
- if(!p->pType->public_visible) {
- p->public_visible=0;
- }
- }
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity visible_hidden_subtract */
- static int OOMethod_OOEntity_visible_hidden_subtract(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(p->public_hidden==0) {
- p->public_visible=0;
- }
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity visible_inherit */
- static int OOMethod_OOEntity_visible_inherit(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(p->pType) {
- if(p->pType->public_hidden) {
- p->public_hidden=1;
- p->public_visible=0;
- } else {
- if(p->pType->public_visible) {
- p->public_visible=1;
- }
- p->public_hidden=0;
- }
- }
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity visible_reset */
- static int OOMethod_OOEntity_visible_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- i = SimType_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_visible=0;
- p->public_trace=0;
- p->public_hidden=0;
- i = Tcl_NextHashEntry(&search);
- }
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_visible=0;
- p->public_trace=0;
- p->public_hidden=0;
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity visible_tree */
- static int OOMethod_OOEntity_visible_tree(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- /*
- ** Rebuild the visible and active flags
- ** in simtypes
- */
- i = SimType_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_visible=0;
- p->public_trace=0;
- p->public_hidden=0;
- i = Tcl_NextHashEntry(&search);
- }
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_visible=0;
- p->public_trace=0;
- p->public_hidden=0;
- i = Tcl_NextHashEntry(&search);
- }
- i = SimType_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- int code=SimType_Walk_Parent(p);
- if(code > 0) {
- p->public_visible=1;
- } else if (code < 0) {
- p->public_visible=0;
- p->public_hidden=1;
- }
- i = Tcl_NextHashEntry(&search);
- }
- i = Entity_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- int code=SimType_Walk_Parent(p->pType);
- if(code==1) {
- p->public_visible=1;
- } else if (code < 0) {
- p->public_visible=0;
- p->public_hidden=1;
- }
- i = Tcl_NextHashEntry(&search);
- }
- return TCL_OK;
- }
- /* OO Method OOEntity witheach */
- static int OOMethod_OOEntity_witheach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- local_interp=interp;
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- int searchresult=TCL_OK;
- Tcl_Obj *body,*matchvalues=NULL;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- if( objc != 3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "?matchlist? body");
- return TCL_ERROR;
- }
- if(objc==3) {
- body=objv[2];
- } else {
- matchvalues=objv[2];
- body=objv[3];
- }
- if(Entity_BuildMatch(interp,matchvalues,matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=Entity_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(matchvalues) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- searchresult=Entity_nodeeval(interp,p,body,1);
- if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
- Odie_Free((char *)searchPtr);
- return searchresult;
- }
- }
- Odie_Free((char *)searchPtr);
- return TCL_OK;
- }
- /* Loader for OOEntity */
- static int OOEntity_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::entity" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::entity" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::entity", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- nameObj=Tcl_NewStringObj("C_Init",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_C_Init, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("create",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("add",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("attach_to",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_attach_to, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("compartment",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_compartment, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("comptid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_comptid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("count",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_count, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("deckid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_deckid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("drawn_reset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_drawn_reset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("exists",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_exists, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("for",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_for, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("foreach",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_foreach, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("groupid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_groupid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("groups_recalculate",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_groups_recalculate, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("hidden_inherit",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_hidden_inherit, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("location",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_location, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("midpoint",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_midpoint, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nodeget",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_nodeget, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nodeput",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_nodeput, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nodewith",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_nodewith, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("normalize",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_normalize, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("orientation",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_orientation, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("redraw",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_redraw, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("reset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_reset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("setting",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_setting, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("spec_get",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_spec_get, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("spec_put",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_spec_put, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("spec_replace",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_spec_replace, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("struct_get",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_struct_get, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("struct_put",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_struct_put, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("type",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_type, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("typeid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_typeid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_visible, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible_filter",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_visible_filter, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible_hidden_subtract",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_visible_hidden_subtract, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible_inherit",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_visible_inherit, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible_reset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_visible_reset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible_tree",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_visible_tree, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("witheach",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_OOEntity_witheach, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* OO Method SimType C_Init */
- static int OOMethod_SimType_C_Init(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Simulator *p;
- Tcl_Object masterObject;
- if(objc!=3) {
- Tcl_WrongNumArgs(interp, 2, objv, "SIMULATOR_OBJECT");
- return TCL_ERROR;
- }
- masterObject=Tcl_GetObjectFromObj(interp,objv[2]);
- if(masterObject==NULL) {
- return TCL_ERROR;
- }
- p=GETSIMULATOR(masterObject);
- Tcl_ObjectSetMetadata(thisObject, &SimulatorDataType, (ClientData) p);
- return TCL_OK;
- }
- /* OO Method SimType children */
- static int OOMethod_SimType_children(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- Roid id;
- if( objc!=3 ) {
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- }
- if(Irm_GetRoidFromObj(interp,objv[2],&id)) return TCL_ERROR;
- CurrentSim=GETSIMULATOR(thisObject);
- i = SimType_First(CurrentSim,&search);
- while( i ){
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- int match=0;
- if(!id && !p->public_parent) {
- match=1;
- }
- if(p->public_parent) {
- if(p->public_parent == id) {
- match=1;
- }
- }
- if(match) {
- Tcl_Obj *namevalue=Entity_GetField(NULL,p->infoDict,"name");
- if(!namevalue) {
- namevalue=Irm_NewRoidObj(p->id);
- }
- Tcl_ListObjAppendElement(0, pResult, namevalue);
- Tcl_ListObjAppendElement(0, pResult, Irm_NewRoidObj(p->id));
- }
- i = Tcl_NextHashEntry(&search);
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SimType count */
- static int OOMethod_SimType_count(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- int domatch=0;
- int result=0;
- CurrentSim=GETSIMULATOR(thisObject);
- if(objc>2) {
- domatch=1;
- if(Entity_BuildMatch(interp,objv[2],matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- for(i=SimType_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(domatch) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- result++;
- }
- Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
- return TCL_OK;
- }
- /* OO Method SimType create */
- static int OOMethod_SimType_create(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *pType;
- Roid id;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Irm_GetRoidFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- CurrentSim=GETSIMULATOR(thisObject);
- pType = SimType_ById(id, 1);
- Tcl_SetObjResult(interp, Irm_NewRoidObj(pType->id));
- return TCL_OK;
- }
- /* OO Method SimType delete */
- static int OOMethod_SimType_delete(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Roid id;
- Entity *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( Irm_GetRoidFromObj(interp, objv[2], &id) ) return TCL_ERROR;
- CurrentSim=GETSIMULATOR(thisObject);
- p=SimType_ById(id,0);
- if(p==0 ){
- return TCL_OK;
- }
- SimType_Unlink(p);
- Entity_StructFree(p);
- Odie_Free((char *)p);
- return TCL_OK;
- }
- /* OO Method SimType exists */
- static int OOMethod_SimType_exists(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Entity *pType;
- Roid id;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- if( Irm_GetRoidFromObj(interp, objv[2], &id) ) {
- Tcl_ResetResult(interp);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- pType = SimType_ById(id, 0);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pType > 0));
- return TCL_OK;
- }
- /* OO Method SimType for */
- static int OOMethod_SimType_for(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- int searchresult=TCL_OK;
- Tcl_Obj *keyvar;
- Tcl_Obj *infovar=NULL;
- Tcl_Obj *body;
- if( objc != 4 && objc != 5){
- Tcl_WrongNumArgs(interp, 2, objv, "keyvar ?valvar? body");
- return TCL_ERROR;
- }
- CurrentSim=GETSIMULATOR(thisObject);
- keyvar=objv[2];
- if (objc == 5) {
- infovar=objv[3];
- body=objv[4];
- } else {
- body=objv[4];
- }
- Tcl_IncrRefCount(keyvar);
- Tcl_IncrRefCount(body);
- if(infovar) {
- Tcl_IncrRefCount(infovar);
- }
- searchresult=TCL_OK;
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=SimType_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity *)Tcl_GetHashValue(i);
- Tcl_ObjSetVar2(interp, keyvar, (Tcl_Obj *)NULL, SimType_Identify(p), 0);
- if(infovar) {
- Tcl_ObjSetVar2(interp, infovar, (Tcl_Obj *)NULL, Entity_StructToDict(interp,p,1), 0);
- }
- searchresult=Tcl_EvalObjEx(interp,body,0);
- if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
- break;
- }
- }
- Tcl_DecrRefCount(keyvar);
- if(infovar) {
- Tcl_DecrRefCount(infovar);
- }
- Tcl_DecrRefCount(body);
- Odie_Free((char *)searchPtr);
- return searchresult;
- }
- /* OO Method SimType foreach */
- static int OOMethod_SimType_foreach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- int searchresult=TCL_OK;
- Tcl_Obj *body,*matchvalues=NULL;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- CurrentSim=GETSIMULATOR(thisObject);
- if( objc != 3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "?matchlist? body");
- return TCL_ERROR;
- }
- if(objc==3) {
- body=objv[2];
- } else {
- matchvalues=objv[2];
- body=objv[3];
- }
- if(Entity_BuildMatch(interp,matchvalues,matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=SimType_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(matchvalues) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- searchresult=Entity_nodeeval(interp,p,body,0);
- if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
- Odie_Free((char *)searchPtr);
- return searchresult;
- }
- }
- Odie_Free((char *)searchPtr);
- return TCL_OK;
- }
- /* OO Method SimType groupid */
- static int OOMethod_SimType_groupid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Roid groupid=0;
- if( objc!=3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?groupid?");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) {
- Tcl_ResetResult(interp);
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- return TCL_OK;
- }
- if(objc==4) {
- if(Irm_GetRoidFromObj(interp,objv[3],&groupid)) {
- return TCL_ERROR;
- }
- SimType_StructSetGroup(p,groupid);
- }
- groupid=SimType_StructGetGroup(p);
- if(groupid>0) {
- Tcl_SetObjResult(interp, Irm_NewRoidObj(groupid));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- /* OO Method SimType list */
- static int OOMethod_SimType_list(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Tcl_Obj *pResult = Tcl_NewObj();
- Tcl_HashSearch search;
- Tcl_HashEntry *i;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- int domatch=0;
- if(objc==3) {
- domatch=1;
- if(Entity_BuildMatch(interp,objv[2],matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- }
- for(i=SimType_First(CurrentSim,&search); i ; i = Tcl_NextHashEntry(&search)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(domatch) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- Tcl_ListObjAppendElement(interp, pResult, SimType_Identify(p));
- }
- Tcl_SetObjResult(interp, pResult);
- return TCL_OK;
- }
- /* OO Method SimType nodeget */
- static int OOMethod_SimType_nodeget(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- if( objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field?");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==4) {
- Tcl_Obj *result;
- int offset=-1,err,type;
- err=Entity_StructValueOffset(interp, objv[3], &offset,&type);
- if(err == TCL_OK ) {
- result=Entity_StructGet(p,offset);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Pull the value from extended dict */
- result=Entity_SpecHashGet(p,objv[3],ODIE_NULL_EMPTY);
- Tcl_SetObjResult(interp,result);
- } else {
- Tcl_SetObjResult(interp,Entity_StructToDict(interp,p,1));
- }
- return TCL_OK;
- }
- /* OO Method SimType nodeput */
- static int OOMethod_SimType_nodeput(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Tcl_DictSearch search;
- Tcl_Obj *key, *value, *objPtr;
- int done;
- int offset,type,err=TCL_OK;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- if( Entity_StructValueOffset(interp, key, &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,p,offset,value);
- if(err != TCL_OK) {
- break;
- }
- } else {
- Entity_SpecHashPut(p,key,value);
- Tcl_SetObjResult(interp, value);
- }
- }
- Tcl_DictObjDone(&search);
- if(err==TCL_OK) {
- SimType_ApplySettings(p);
- }
- return err;
- }
- /* OO Method SimType nodewith */
- static int OOMethod_SimType_nodewith(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- if( objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID body");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- return SimType_nodeeval(interp,p,objv[3],1);
- }
- /* OO Method SimType normalize */
- static int OOMethod_SimType_normalize(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- if( objc!=3 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- } else {
- Tcl_SetObjResult(interp, SimType_Identify(p));
- }
- return TCL_OK;
- }
- /* OO Method SimType parent */
- static int OOMethod_SimType_parent(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- if( objc!=3){
- Tcl_WrongNumArgs(interp, 2, objv, "ID");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- Tcl_SetObjResult(interp, Irm_NewRoidObj(p->public_parent));
- return TCL_OK;
- }
- /* OO Method SimType setting */
- static int OOMethod_SimType_setting(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- int offset,type,rcode;
- /* If given a new value, act like a stylized set */
- Entity *p;
- if( objc!=4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID FIELD ?VALUE?");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc == 5) {
- if( Entity_StructValueOffset(interp, objv[3], &offset, &type) == TCL_OK ) {
- rcode=Entity_StructSet(interp,p,offset,objv[4]);
- return rcode;
- }
- rcode=Entity_SetFromObj(interp,p,objv[3],objv[4]);
- return rcode;
- } else {
- Tcl_Obj *result;
- int offset=-1,err,type;
- err=Entity_StructValueOffset(interp, objv[3], &offset,&type);
- if(err == TCL_OK ) {
- result=Entity_StructGet(p,offset);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- /* Pull the value from extended dict */
- result=Entity_ExportField(p->pType,p->infoDict,Tcl_GetString(objv[3]),ODIE_NULL_ZERO);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- }
- /* OO Method SimType spec_get */
- static int OOMethod_SimType_spec_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Tcl_Obj *pResult=NULL;
- if( objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field?");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==3) {
- /* Pull the value from extended dict */
- pResult=Entity_SpecHashGet(p,objv[3],ODIE_NULL_EMPTY);
- } else {
- pResult=Entity_GetDict(p->pType,p->infoDict);
- }
- if(pResult) {
- Tcl_SetObjResult(interp,pResult);
- }
- return TCL_OK;
- }
- /* OO Method SimType spec_put */
- static int OOMethod_SimType_spec_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Tcl_DictSearch search;
- Tcl_Obj *key, *value, *objPtr;
- int done;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- Entity_SpecHashPut(p,key,value);
- Tcl_SetObjResult(interp, value);
- }
- Tcl_DictObjDone(&search);
- return TCL_OK;
- }
- /* OO Method SimType spec_replace */
- static int OOMethod_SimType_spec_replace(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Tcl_DictSearch search;
- Tcl_Obj *key, *value, *objPtr;
- int done;
- if( objc!=4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- Entity_SpecHashClear(p);
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- Entity_SpecHashPut(p,key,value);
- Tcl_SetObjResult(interp, value);
- }
- Tcl_DictObjDone(&search);
- return TCL_OK;
- }
- /* OO Method SimType struct_get */
- static int OOMethod_SimType_struct_get(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- if( objc!=3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?field?");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==4) {
- Tcl_Obj *result;
- int offset=-1,err,type;
- err=Entity_StructValueOffset(interp, objv[3], &offset,&type);
- if(err == TCL_OK ) {
- result=Entity_StructGet(p,offset);
- Tcl_SetObjResult(interp,result);
- return TCL_OK;
- }
- return TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp,Entity_StructToDict(interp,p,0));
- }
- return TCL_OK;
- }
- /* OO Method SimType struct_put */
- static int OOMethod_SimType_struct_put(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Tcl_DictSearch search;
- int done;
- int offset,type,err=TCL_OK;
- if( objc!=4 && objc!=5 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID infoDict");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==5) {
- if( Entity_StructValueOffset(interp, objv[3], &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,p,offset,objv[4]);
- if(err != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- return TCL_ERROR;
- }
- } else {
- Tcl_Obj *key, *value;
- Tcl_Obj *objPtr=objv[3];
- if (Tcl_DictObjFirst(interp, objPtr, &search,
- &key, &value, &done) != TCL_OK) {
- return TCL_ERROR;
- }
- for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) {
- if( Entity_StructValueOffset(interp, key, &offset, &type) == TCL_OK ) {
- err=Entity_StructSet(interp,p,offset,value);
- if(err != TCL_OK) {
- break;
- }
- } else {
- return TCL_ERROR;
- }
- }
- Tcl_DictObjDone(&search);
- }
- if(err==TCL_OK) {
- SimType_ApplySettings(p);
- }
- return err;
- }
- /* OO Method SimType type */
- static int OOMethod_SimType_type(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Entity *pType;
- if( objc != 3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "NODEID field");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- pType=SimType_StructGetType(p);
- if(!pType) {
- if(objc==3) {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- if(objc==3) {
- Tcl_SetObjResult(interp, SimType_Identify(pType));
- }
- if(objc==4) {
- Tcl_Obj *pResult;
- pResult=Entity_ExportField(pType,NULL,Tcl_GetString(objv[3]),ODIE_NULL_EMPTY);
- Tcl_SetObjResult(interp,pResult);
- }
- return TCL_OK;
- }
- /* OO Method SimType typeid */
- static int OOMethod_SimType_typeid(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Entity *p;
- Entity *pType;
- if( objc!=3 && objc != 4 ){
- Tcl_WrongNumArgs(interp, 2, objv, "ID ?typeid?");
- return TCL_ERROR;
- }
- if( SimType_FromTclObj(interp, objv[2], &p) ) return TCL_ERROR;
- if(objc==3) {
- if( SimType_FromTclObj(interp, objv[3], &pType) ) {
- /* Translate a ZERO length list to null */
- int len;
- if(Tcl_ListObjLength(NULL,objv[3],&len)) {
- return TCL_ERROR;
- }
- if(len) {
- int intval;
- if(Tcl_GetIntFromObj(NULL,objv[3],&intval)==TCL_ERROR) {
- return TCL_ERROR;
- }
- if(intval>0) {
- return TCL_ERROR;
- }
- }
- Tcl_ResetResult(interp);
- pType=NULL;
- }
- SimType_StructSetType(p,pType);
- /* Reset the group pointer so it's recalculated */
- SimType_StructSetGroup(p,-1);
- }
- pType=SimType_StructGetType(p);
- if(pType) {
- Tcl_SetObjResult(interp, SimType_Identify(pType));
- } else {
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
- }
- return TCL_OK;
- }
- /* OO Method SimType visible_reset */
- static int OOMethod_SimType_visible_reset(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=SimType_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- p->public_visible=0;
- p->public_hidden=0;
- p->public_active=0;
- p->public_oncount=0;
- p->public_drawn=0;
- }
- Odie_Free((char *)searchPtr);
- return TCL_OK;
- }
- /* OO Method SimType witheach */
- static int OOMethod_SimType_witheach(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv) {Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */
- CurrentSim=GETSIMULATOR(thisObject);
- Tcl_HashSearch *searchPtr;
- Tcl_HashEntry *i;
- int searchresult=TCL_OK;
- Tcl_Obj *body,*matchvalues=NULL;
- int matchStruct[ENTITY_SEARCH_NCOUNT];
- if( objc != 3 && objc != 4){
- Tcl_WrongNumArgs(interp, 2, objv, "?matchlist? body");
- return TCL_ERROR;
- }
- if(objc==3) {
- body=objv[2];
- } else {
- matchvalues=objv[2];
- body=objv[3];
- }
- if(Entity_BuildMatch(interp,matchvalues,matchStruct) != TCL_OK) {
- return TCL_ERROR;
- }
- searchPtr=(Tcl_HashSearch *)Odie_Alloc(sizeof(Tcl_HashSearch));
- for(i=SimType_First(CurrentSim,searchPtr); i ; i = Tcl_NextHashEntry(searchPtr)) {
- Entity *p = (Entity*)Tcl_GetHashValue(i);
- if(matchvalues) {
- if(!Entity_StructMatches(p,matchStruct)) continue;
- }
- searchresult=Entity_nodeeval(interp,p,body,1);
- if (searchresult !=TCL_OK && searchresult!=TCL_CONTINUE) {
- Odie_Free((char *)searchPtr);
- return searchresult;
- }
- }
- Odie_Free((char *)searchPtr);
- return TCL_OK;
- }
- /* Loader for SimType */
- static int SimType_OO_Init(Tcl_Interp *interp) {
- /*
- ** Build the "::odielib::simtype" class
- */
- Tcl_Obj* nameObj; /* Name of a class or method being looked up */
- Tcl_Object curClassObject; /* Tcl_Object representing the current class */
- Tcl_Class curClass; /* Tcl_Class representing the current class */
- /*
- * Find the "::odielib::simtype" class, and attach an 'init' method to it.
- */
- nameObj = Tcl_NewStringObj("::odielib::simtype", -1);
- Tcl_IncrRefCount(nameObj);
- if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) {
- Tcl_DecrRefCount(nameObj);
- return TCL_ERROR;
- }
- Tcl_DecrRefCount(nameObj);
- curClass = Tcl_GetObjectAsClass(curClassObject);
- nameObj=Tcl_NewStringObj("C_Init",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_C_Init, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("children",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_children, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("count",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_count, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("create",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_create, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("delete",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_delete, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("exists",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_exists, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("for",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_for, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("foreach",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_foreach, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("groupid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_groupid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("list",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_list, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nodeget",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_nodeget, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nodeput",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_nodeput, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("nodewith",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_nodewith, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("normalize",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_normalize, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("parent",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_parent, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("setting",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_setting, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("spec_get",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_spec_get, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("spec_put",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_spec_put, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("spec_replace",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_spec_replace, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("struct_get",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_struct_get, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("struct_put",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_struct_put, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("type",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_type, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("typeid",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_typeid, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("visible_reset",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_visible_reset, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- nameObj=Tcl_NewStringObj("witheach",-1);
- Tcl_NewMethod(interp, curClass, nameObj, 1, &OOMethodType_SimType_witheach, (ClientData) NULL);
- Tcl_DecrRefCount(nameObj);
- return TCL_OK;
- }
- /* END generate-cfile-tclapi */
- extern int DLLEXPORT Odielibc_Init( Tcl_Interp *interp ) {
- /* Initialise the stubs tables. */
- #ifdef USE_TCL_STUBS
- if (Tcl_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR;
- if (TclOOInitializeStubs(interp, "1.0") == NULL) return TCL_ERROR;
- #endif
- if(interp) {
- if(Tcl_Eval(interp,
- "\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygon.tcl\n" \
- "namespace eval ::polygon {}\n" \
- "###\n" \
- "# Decompose a concave polygon into a set of convex polygons\n" \
- "###\n" \
- "proc ::polygon::convex_decompose POLY {\n" \
- " if {[is_convex $POLY]} {\n" \
- " return [list $POLY]\n" \
- " }\n" \
- " set SEGMENTS [::odielib::segset new]\n" \
- " $SEGMENTS polygon_add 1 $POLY\n" \
- " $SEGMENTS make_convex\n" \
- " set result [$SEGMENTS polygons]\n" \
- " $SEGMENTS destroy\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygon::set_union args {\n" \
- " set SEGMENTS [::odielib::segset new]\n" \
- " set polycount 0\n" \
- " foreach poly $args {\n" \
- " incr polycount\n" \
- " set POLYGONS($polycount) $poly\n" \
- " $SEGMENTS polygon_add $polycount $POLYGONS($polycount)\n" \
- " }\n" \
- " set cleanup [$SEGMENTS cleanup]\n" \
- " set cleanup [$SEGMENTS cleanup]\n" \
- " set connections {}\n" \
- " set newseg {}\n" \
- " for {set i 1} {$i <= $polycount} {incr i} {\n" \
- " set COORDS [coords $POLYGONS($i)]\n" \
- " for {set j 1} {$j <= $polycount} {incr j} {\n" \
- " if {$i==$j} continue\n" \
- " foreach vertex $COORDS {\n" \
- " if {$vertex in $connections} continue\n" \
- " set within [within $vertex $POLYGONS($j)]\n" \
- " if {$within>0} {\n" \
- " set connection [$SEGMENTS edge_connection $vertex $j]\n" \
- " if {![::vector::is_null $connection]} {\n" \
- " lappend newseg $vertex $connection\n" \
- " lappend connections $vertex\n" \
- " }\n" \
- " }\n" \
- " }\n" \
- " }\n" \
- " }\n" \
- " foreach {v c} $newseg {\n" \
- " $SEGMENTS segment_add_virtual $v $c\n" \
- " }\n" \
- " $SEGMENTS make_convex\n" \
- " set result [$SEGMENTS polygons]\n" \
- " $SEGMENTS destroy\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygon::set_intersection {UNION args} {\n" \
- " set result {}\n" \
- " set id 0\n" \
- " set result {}\n" \
- " foreach poly $UNION {\n" \
- " set match 1\n" \
- " set center [center $poly]\n" \
- " foreach ipoly $args {\n" \
- " if {[within {*}[::vectorxy::flatten $center] $ipoly]<0} {\n" \
- " set match 0\n" \
- " break\n" \
- " }\n" \
- " }\n" \
- " if {$match} {\n" \
- " lappend result $poly\n" \
- " }\n" \
- " }\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygon::set_difference {UNION args} {\n" \
- " set result {}\n" \
- " set id 0\n" \
- " set result {}\n" \
- " foreach poly $UNION {\n" \
- " set match 1\n" \
- " set center [center $poly]\n" \
- " foreach ipoly $args {\n" \
- " if {[within {*}[vectorxy::flatten $center] $ipoly]>=0} {\n" \
- " set match 0\n" \
- " break\n" \
- " }\n" \
- " }\n" \
- " if {$match} {\n" \
- " lappend result $poly\n" \
- " }\n" \
- " }\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygon::within_concave {A POLY} {\n" \
- " if {[is_convex $POLY]} {\n" \
- " return [within {*}[vectorxy::flatten $A] $POLY]\n" \
- " }\n" \
- " set polylist [convex_decompose $POLY]\n" \
- " return [within {*}[vectorxy::flatten $A] {*}$polylist]\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygon.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygonxyz.tcl\n" \
- "namespace eval ::polygonxyz {}\n" \
- "###\n" \
- "# Decompose a concave polygon into a set of convex polygons\n" \
- "###\n" \
- "proc ::polygonxyz::convex_decompose POLY {\n" \
- " if {[is_convex $POLY]} {\n" \
- " return [list $POLY]\n" \
- " }\n" \
- " set SEGMENTS [::odielib::segset new]\n" \
- " $SEGMENTS uv_transform polygon $POLY\n" \
- " $SEGMENTS polygon_add 1 $POLY\n" \
- " $SEGMENTS make_convex\n" \
- " set result [$SEGMENTS polygons]\n" \
- " $SEGMENTS destroy\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygonxyz::set_union args {\n" \
- " set SEGMENTS [::odielib::segset new]\n" \
- " $SEGMENTS uv_transform polygon [lindex $args 0]\n" \
- " set polycount 0\n" \
- " foreach poly $args {\n" \
- " incr polycount\n" \
- " set POLYGONS($polycount) $poly\n" \
- " $SEGMENTS polygon_add $polycount $POLYGONS($polycount)\n" \
- " }\n" \
- " set cleanup [$SEGMENTS cleanup]\n" \
- " set cleanup [$SEGMENTS cleanup]\n" \
- " set connections {}\n" \
- " set newseg {}\n" \
- " for {set i 1} {$i <= $polycount} {incr i} {\n" \
- " set COORDS [coords $POLYGONS($i)]\n" \
- " for {set j 1} {$j <= $polycount} {incr j} {\n" \
- " if {$i==$j} continue\n" \
- " foreach vertex $COORDS {\n" \
- " if {$vertex in $connections} continue\n" \
- " set within [within $vertex $POLYGONS($j)]\n" \
- " if {$within>0} {\n" \
- " set connection [$SEGMENTS edge_connection $vertex $j]\n" \
- " if {![::vector::is_null $connection]} {\n" \
- " lappend newseg $vertex $connection\n" \
- " lappend connections $vertex\n" \
- " }\n" \
- " }\n" \
- " }\n" \
- " }\n" \
- " }\n" \
- " foreach {v c} $newseg {\n" \
- " $SEGMENTS segment_add_virtual $v $c\n" \
- " }\n" \
- " $SEGMENTS make_convex\n" \
- " set result [$SEGMENTS polygons]\n" \
- " $SEGMENTS destroy\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygonxyz::set_intersection {UNION args} {\n" \
- " set result {}\n" \
- " set id 0\n" \
- " set result {}\n" \
- " foreach poly $UNION {\n" \
- " set match 1\n" \
- " set center [center $poly]\n" \
- " foreach ipoly $args {\n" \
- " if {[within $center $ipoly]<0} {\n" \
- " set match 0\n" \
- " break\n" \
- " }\n" \
- " }\n" \
- " if {$match} {\n" \
- " lappend result $poly\n" \
- " }\n" \
- " }\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygonxyz::set_difference {UNION args} {\n" \
- " set result {}\n" \
- " set id 0\n" \
- " set result {}\n" \
- " foreach poly $UNION {\n" \
- " set match 1\n" \
- " set center [center $poly]\n" \
- " foreach ipoly $args {\n" \
- " if {[within $center $ipoly]>=0} {\n" \
- " set match 0\n" \
- " break\n" \
- " }\n" \
- " }\n" \
- " if {$match} {\n" \
- " lappend result $poly\n" \
- " }\n" \
- " }\n" \
- " return $result\n" \
- "}\n" \
- "\n" \
- "proc ::polygonxyz::within_concave {A POLY} {\n" \
- " if {[is_convex $POLY]} {\n" \
- " return [within $A $POLY]\n" \
- " }\n" \
- " set polylist [convex_decompose $POLY]\n" \
- " return [within_set $A {*}$polylist]\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygonxyz.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/segset.tcl\n" \
- "if {[info command ::odielib::segset] eq {}} {\n" \
- "::oo::class create ::odielib::segset {\n" \
- " constructor {} {\n" \
- " my SegmentSet_Init\n" \
- " }\n" \
- "\n" \
- " method fix_coincident {} {\n" \
- " set fixes 0\n" \
- " for {set count 0} {$count < 1000} {incr count} {\n" \
- " my modified 0\n" \
- " foreach problem [my check_coincident] {\n" \
- " my vertex_add [dict get $problem intercept1:] [dict get $problem intercept2:]\n" \
- " }\n" \
- " if {![my modified]} break\n" \
- " incr fixes\n" \
- " }\n" \
- " return $fixes\n" \
- " }\n" \
- "\n" \
- " # Break up oblique angles\n" \
- " method make_convex {} {\n" \
- " set newseg 0\n" \
- " my fix_coincident\n" \
- " for {set count 0} {$count < 128} {incr count} {\n" \
- " my modified 0\n" \
- " foreach {vertex connection} [my check_oblique] {\n" \
- " set c [my segment_add_virtual $vertex $connection]\n" \
- " incr newseg $c\n" \
- " }\n" \
- " if {![my modified]} break\n" \
- " }\n" \
- " return $newseg\n" \
- " }\n" \
- "}\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/segset.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/plotter.tcl\n" \
- "if {[info command ::odielib::plotter] eq {}} {\n" \
- "::oo::class create ::odielib::plotter {\n" \
- "}\n" \
- "}\n" \
- "proc ::plotter name {\n" \
- " ::odielib::plotter create $name\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/plotter.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/slicer.tcl\n" \
- "if {[info command ::odielib::slicer] eq {}} {\n" \
- "::oo::class create ::odielib::slicer {\n" \
- " superclass ::odielib::plotter\n" \
- "\n" \
- " constructor {} {\n" \
- " my Slicer_Init\n" \
- " }\n" \
- "}\n" \
- "}\n" \
- "\n" \
- "proc ::slicer name {\n" \
- " ::odielib::slicer create $name\n" \
- " return $name\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/slicer.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/wallset.tcl\n" \
- "if {[info command ::odielib::wallset] eq {}} {\n" \
- "::oo::class create ::odielib::wallset {\n" \
- "}\n" \
- "}\n" \
- "\n" \
- "proc ::wallset name {\n" \
- " return [::odielib::wallset create $name]\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/wallset.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/faceset.tcl\n" \
- "if {[info command ::odielib::polygonhull] eq {}} {\n" \
- "::oo::class create ::odielib::polygonhull {\n" \
- " constructor {} {\n" \
- " my PolygonHull_Init\n" \
- " }\n" \
- "\n" \
- " method SimplifyStep {} {\n" \
- " puts [list SimplifyStep]\n" \
- " set vol_list [my volume_list]\n" \
- " foreach vid $vol_list {\n" \
- " if {$vid<=0} continue\n" \
- " set volume_center($vid) [my volume_center $vid]\n" \
- " }\n" \
- " set changes 0\n" \
- " set face_list [lsort -integer [my face_list]]\n" \
- " set face_mod {}\n" \
- " foreach id $face_list {\n" \
- " set facepolygon($id) [my face_polygon $id]\n" \
- " set facesides($id) [my face_volume $id]\n" \
- " }\n" \
- " ###\n" \
- " # WHY IS THIS AN INFINITE LOOP?!?!?\n" \
- " ###\n" \
- " foreach i $face_list {\n" \
- " foreach j $face_list {\n" \
- " #if {$j>=$i} continue\n" \
- " if {![::polygon::coplaner $facepolygon($i) $facepolygon($j)]} continue\n" \
- "\n" \
- " set union [::polygon::union $facepolygon($i) $facepolygon($j)]\n" \
- " set intersect [::polygon::intersection $union $facepolygon($i) $facepolygon($j)]\n" \
- " if {![llength $intersect]} continue\n" \
- " incr changes\n" \
- " lappend face_mod $i $j\n" \
- " my face_delete $i\n" \
- " my face_delete $j\n" \
- " set vola [lindex $facesides($i) 1]\n" \
- " set volb [lindex $facesides($j) 1]\n" \
- " foreach poly $intersect {\n" \
- " set id [my face_create $i {*}[::polygon::coords $poly]]\n" \
- " if {$vola>0} {\n" \
- " set sidea [my face_side $id $volume_center($vola)]\n" \
- " my face_volume $id $sidea $vola\n" \
- " }\n" \
- " if {$volb>0} {\n" \
- " set sideb [my face_side $id $volume_center($volb)]\n" \
- " my face_volume $id $sideb $volb\n" \
- " }\n" \
- " }\n" \
- " foreach poly [::polygon::clip $union $facepolygon($i) $facepolygon($j)] {\n" \
- " set id [my face_create -1 {*}[::polygon::coords $poly]]\n" \
- " if {$vola>0} {\n" \
- " set side [my face_side $id $volume_center($vola)]\n" \
- " my face_volume $id $side $vola\n" \
- " }\n" \
- " }\n" \
- " foreach poly [::polygon::clip $union $facepolygon($j) $facepolygon($i)] {\n" \
- " set id [my face_create -1 {*}[::polygon::coords $poly]]\n" \
- " if {$volb>0} {\n" \
- " set side [my face_side $id $volume_center($volb)]\n" \
- " my face_volume $id $side $volb\n" \
- " }\n" \
- " }\n" \
- " return 1\n" \
- " }\n" \
- " }\n" \
- " return $changes\n" \
- " }\n" \
- "\n" \
- " method simplify {} {\n" \
- " puts [list [self] simplify]\n" \
- " set changes 1\n" \
- " set count 0\n" \
- " while {$changes>0} {\n" \
- " if {[incr count]>1000} {\n" \
- " error \"Infinite loop\"\n" \
- " }\n" \
- " set changes [my SimplifyStep]\n" \
- " puts [list [self] simplify $count $changes]\n" \
- " }\n" \
- " }\n" \
- "}\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/faceset.tcl\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl\n" \
- "if {[info command ::odielib::simulator] eq {}} {\n" \
- "::oo::class create ::odielib::simulator {\n" \
- " constructor {} {\n" \
- " my C_Init\n" \
- " }\n" \
- "}\n" \
- "}\n" \
- "if {[info command ::odielib::entity] eq {}} {\n" \
- "::oo::class create ::odielib::entity {\n" \
- " constructor {simulatorObj} {\n" \
- " my C_Init $simulatorObj\n" \
- " }\n" \
- "}\n" \
- "}\n" \
- "if {[info command ::odielib::simtype] eq {}} {\n" \
- "::oo::class create ::odielib::simtype {\n" \
- " constructor {simulatorObj} {\n" \
- " my C_Init $simulatorObj\n" \
- " }\n" \
- "}\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl\n" \
- "\n" )) return TCL_ERROR;
- }
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/odieutil/md5.c */
- if(Md5_Init(interp)!=TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/odieutil/md5.c */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/odieutil/tclextra.c */
- if(TclExtra_Init(interp)!=TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/odieutil/tclextra.c */
- if(Rc4_Init(interp)) return TCL_ERROR;
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/odiemath/odiemath.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::odiemath",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::odiemath", NULL, NULL);
- }
- }
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("1_pi",-1),Tcl_NewDoubleObj(M_1_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_1_PI",-1),NULL,Tcl_NewDoubleObj(M_1_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("2_pi",-1),Tcl_NewDoubleObj(M_2_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_2_PI",-1),NULL,Tcl_NewDoubleObj(M_2_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("2_sqrtpi",-1),Tcl_NewDoubleObj(M_2_SQRTPI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_2_SQRTPI",-1),NULL,Tcl_NewDoubleObj(M_2_SQRTPI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("e",-1),Tcl_NewDoubleObj(M_E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_E",-1),NULL,Tcl_NewDoubleObj(M_E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("ln2",-1),Tcl_NewDoubleObj(M_LN2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_LN2",-1),NULL,Tcl_NewDoubleObj(M_LN2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("ln10",-1),Tcl_NewDoubleObj(M_LN10),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_LN10",-1),NULL,Tcl_NewDoubleObj(M_LN10),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("log2e",-1),Tcl_NewDoubleObj(M_LOG2E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_LOG2E",-1),NULL,Tcl_NewDoubleObj(M_LOG2E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("log10e",-1),Tcl_NewDoubleObj(M_LOG10E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_LOG10E",-1),NULL,Tcl_NewDoubleObj(M_LOG10E),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("pi",-1),Tcl_NewDoubleObj(M_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_PI",-1),NULL,Tcl_NewDoubleObj(M_PI),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("pi_2",-1),Tcl_NewDoubleObj(M_PI_2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_PI_2",-1),NULL,Tcl_NewDoubleObj(M_PI_2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("pi_4",-1),Tcl_NewDoubleObj(M_PI_4),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_PI_4",-1),NULL,Tcl_NewDoubleObj(M_PI_4),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("sqrt1_2",-1),Tcl_NewDoubleObj(M_SQRT1_2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_SQRT1_2",-1),NULL,Tcl_NewDoubleObj(M_SQRT1_2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::const",-1),Tcl_NewStringObj("sqrt2",-1),Tcl_NewDoubleObj(M_SQRT2),TCL_GLOBAL_ONLY);
- Tcl_ObjSetVar2(interp,Tcl_NewStringObj("::odiemath::M_SQRT2",-1),NULL,Tcl_NewDoubleObj(M_SQRT2),TCL_GLOBAL_ONLY);
- Tcl_CreateObjCommand(interp,"::odiemath::distance",(Tcl_ObjCmdProc *)TclCmd_odiemath_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::dist3d",(Tcl_ObjCmdProc *)TclCmd_odiemath_dist3d,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::grid_hex",(Tcl_ObjCmdProc *)TclCmd_odiemath_grid_hex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::grid_round",(Tcl_ObjCmdProc *)TclCmd_odiemath_grid_round,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::grid_square",(Tcl_ObjCmdProc *)TclCmd_odiemath_grid_square,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::list_round",(Tcl_ObjCmdProc *)TclCmd_odiemath_list_round,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::list_to_int",(Tcl_ObjCmdProc *)TclCmd_odiemath_list_to_int,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::matrix_rotate_angle",(Tcl_ObjCmdProc *)TclCmd_odiemath_matrix_rotate_angle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::matrix_rotate_normal",(Tcl_ObjCmdProc *)TclCmd_odiemath_matrix_rotate_normal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::normal",(Tcl_ObjCmdProc *)TclCmd_odiemath_normal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::perpendicular",(Tcl_ObjCmdProc *)TclCmd_odiemath_perpendicular,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::normal_2d",(Tcl_ObjCmdProc *)TclCmd_odiemath_normal_2d,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::parallel_segment",(Tcl_ObjCmdProc *)TclCmd_odiemath_parallel_segment,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::vector_length",(Tcl_ObjCmdProc *)TclCmd_odiemath_vector_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::vector_rotate_and_size",(Tcl_ObjCmdProc *)TclCmd_odiemath_vector_rotate_and_size,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::vector_scale",(Tcl_ObjCmdProc *)TclCmd_odiemath_vector_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::vector_translate_and_zoom",(Tcl_ObjCmdProc *)TclCmd_odiemath_vector_translate_and_zoom,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::grid",(Tcl_ObjCmdProc *)TclCmd_odiemath_grid,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::tolerance",(Tcl_ObjCmdProc *)TclCmd_odiemath_tolerance,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::odiemath",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/odiemath/odiemath.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/aabb.tcl */
- Tcl_CreateObjCommand(interp,"::odie::aabb::create",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::bbox_overlap_two_vectors",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::overlap_two_vectors",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_overlap_two_vectors,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::bbox_overlap_two_vectors",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_overlap_two_vectors,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::measure",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_measure,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::bbox_measure",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_measure,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::faces",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_faces,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::from_vectorxyz",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_from_vectorxyz,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::to_aabb",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_from_vectorxyz,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::from_line",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_from_line,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::aabb_line",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_from_line,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::from_center_size",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_from_center_size,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::aabb_center_size",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_from_center_size,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::intersect",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::aabb_intersect",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::aabb::within",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_within,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::within_aabb",(Tcl_ObjCmdProc *)TclCmd_odie_aabb_within,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/aabb.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine2d.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::affine2d",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::affine2d", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::affine2d::apply",(Tcl_ObjCmdProc *)TclCmd_affine2d_apply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine2d::combine",(Tcl_ObjCmdProc *)TclCmd_affine2d_combine,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::affine_combine",(Tcl_ObjCmdProc *)TclCmd_affine2d_combine,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine2d::rotation_from_angle",(Tcl_ObjCmdProc *)TclCmd_affine2d_rotation_from_angle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine2d::rotation_from_normal",(Tcl_ObjCmdProc *)TclCmd_affine2d_rotation_from_normal,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::affine2d",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine2d.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine3d.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::affine4x4",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::affine4x4", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::affine4x4::compare",(Tcl_ObjCmdProc *)TclCmd_affine4x4_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::identity",(Tcl_ObjCmdProc *)TclCmd_affine4x4_identity,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::translation",(Tcl_ObjCmdProc *)TclCmd_affine4x4_translation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::scale",(Tcl_ObjCmdProc *)TclCmd_affine4x4_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_nutation",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_nutation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_x",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_nutation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_pitch",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_nutation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_precession",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_precession,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_y",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_precession,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_yaw",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_precession,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_spin",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_spin,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_z",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_spin,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::rotate_roll",(Tcl_ObjCmdProc *)TclCmd_affine4x4_rotate_spin,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::from_euler",(Tcl_ObjCmdProc *)TclCmd_affine4x4_from_euler,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::multiply",(Tcl_ObjCmdProc *)TclCmd_affine4x4_multiply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::X",(Tcl_ObjCmdProc *)TclCmd_affine4x4_multiply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::multiply_inplace",(Tcl_ObjCmdProc *)TclCmd_affine4x4_multiply_inplace,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::X=",(Tcl_ObjCmdProc *)TclCmd_affine4x4_multiply_inplace,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::inverse",(Tcl_ObjCmdProc *)TclCmd_affine4x4_inverse,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::affine4x4::from_normal",(Tcl_ObjCmdProc *)TclCmd_affine4x4_from_normal,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::affine4x4",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/affine3d.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/bbox.tcl */
- Tcl_CreateObjCommand(interp,"::odie::bbox::create",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,":vectorxy::bbox_create",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::bbox::measure",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_measure,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::bbox_measure",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_measure,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::bbox::elements",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_elements,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::bbox_elements",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_elements,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::bbox::intersect",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::bbox_intersect",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::bbox::within",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_within,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::bbox_within",(Tcl_ObjCmdProc *)TclCmd_odie_bbox_within,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/bbox.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/quaternion.tcl */
- Tcl_CreateObjCommand(interp,"::quaternion::add",(Tcl_ObjCmdProc *)TclCmd_quaternion_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::+",(Tcl_ObjCmdProc *)TclCmd_quaternion_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::subtract",(Tcl_ObjCmdProc *)TclCmd_quaternion_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::-",(Tcl_ObjCmdProc *)TclCmd_quaternion_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::multiply",(Tcl_ObjCmdProc *)TclCmd_quaternion_multiply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::*",(Tcl_ObjCmdProc *)TclCmd_quaternion_multiply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::divide",(Tcl_ObjCmdProc *)TclCmd_quaternion_divide,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::/",(Tcl_ObjCmdProc *)TclCmd_quaternion_divide,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::square_root",(Tcl_ObjCmdProc *)TclCmd_quaternion_square_root,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::sqrt",(Tcl_ObjCmdProc *)TclCmd_quaternion_square_root,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::square",(Tcl_ObjCmdProc *)TclCmd_quaternion_square,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::^2",(Tcl_ObjCmdProc *)TclCmd_quaternion_square,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::from_euler",(Tcl_ObjCmdProc *)TclCmd_quaternion_from_euler,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::rotate_by_quaternion",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_rotate_by_quaternion,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::to_euler",(Tcl_ObjCmdProc *)TclCmd_quaternion_to_euler,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::quaternion::from_normal",(Tcl_ObjCmdProc *)TclCmd_quaternion_from_normal,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/quaternion.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vector",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::vector", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::odie::tolerance",(Tcl_ObjCmdProc *)TclCmd_odie_tolerance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::tolerance",(Tcl_ObjCmdProc *)TclCmd_odie_tolerance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::to_list",(Tcl_ObjCmdProc *)TclCmd_odie_vector_to_list,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::to_list",(Tcl_ObjCmdProc *)TclCmd_odie_vector_to_list,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::index",(Tcl_ObjCmdProc *)TclCmd_odie_vector_index,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::index",(Tcl_ObjCmdProc *)TclCmd_odie_vector_index,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::add",(Tcl_ObjCmdProc *)TclCmd_odie_vector_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::add",(Tcl_ObjCmdProc *)TclCmd_odie_vector_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::is_null",(Tcl_ObjCmdProc *)TclCmd_odie_vector_is_null,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::is_null",(Tcl_ObjCmdProc *)TclCmd_odie_vector_is_null,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::is_null",(Tcl_ObjCmdProc *)TclCmd_odie_vector_is_null,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::is_null",(Tcl_ObjCmdProc *)TclCmd_odie_vector_is_null,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::subtract",(Tcl_ObjCmdProc *)TclCmd_odie_vector_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::subtract",(Tcl_ObjCmdProc *)TclCmd_odie_vector_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::midpoint",(Tcl_ObjCmdProc *)TclCmd_odie_vector_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::midpoint",(Tcl_ObjCmdProc *)TclCmd_odie_vector_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::reciprocal",(Tcl_ObjCmdProc *)TclCmd_odie_vector_reciprocal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::reciprocal",(Tcl_ObjCmdProc *)TclCmd_odie_vector_reciprocal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::dot_product",(Tcl_ObjCmdProc *)TclCmd_odie_vector_dot_product,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::dot_product",(Tcl_ObjCmdProc *)TclCmd_odie_vector_dot_product,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::to_matrix",(Tcl_ObjCmdProc *)TclCmd_odie_vector_to_matrix,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::to_matrix",(Tcl_ObjCmdProc *)TclCmd_odie_vector_to_matrix,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::to_fuzzy",(Tcl_ObjCmdProc *)TclCmd_odie_vector_to_fuzzy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::to_fuzzy",(Tcl_ObjCmdProc *)TclCmd_odie_vector_to_fuzzy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::scale",(Tcl_ObjCmdProc *)TclCmd_odie_vector_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::scale",(Tcl_ObjCmdProc *)TclCmd_odie_vector_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::length",(Tcl_ObjCmdProc *)TclCmd_odie_vector_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::length",(Tcl_ObjCmdProc *)TclCmd_odie_vector_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::vector::length_squared",(Tcl_ObjCmdProc *)TclCmd_odie_vector_length_squared,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector::length_squared",(Tcl_ObjCmdProc *)TclCmd_odie_vector_length_squared,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::grid",(Tcl_ObjCmdProc *)TclCmd_odie_grid,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odie::gridvar",(Tcl_ObjCmdProc *)TclCmd_odie_gridvar,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vector",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector2d.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vector2d",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::vector2d", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::vector2d::compare",(Tcl_ObjCmdProc *)TclCmd_vector2d_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::=",(Tcl_ObjCmdProc *)TclCmd_vector2d_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::add",(Tcl_ObjCmdProc *)TclCmd_vector2d_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::+",(Tcl_ObjCmdProc *)TclCmd_vector2d_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::subtract",(Tcl_ObjCmdProc *)TclCmd_vector2d_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::-",(Tcl_ObjCmdProc *)TclCmd_vector2d_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::midpoint",(Tcl_ObjCmdProc *)TclCmd_vector2d_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::-",(Tcl_ObjCmdProc *)TclCmd_vector2d_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::affine_apply",(Tcl_ObjCmdProc *)TclCmd_vector2d_affine_apply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::affine_apply",(Tcl_ObjCmdProc *)TclCmd_vector2d_affine_apply,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::angle",(Tcl_ObjCmdProc *)TclCmd_vector2d_angle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::distance",(Tcl_ObjCmdProc *)TclCmd_vector2d_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::dist2d",(Tcl_ObjCmdProc *)TclCmd_vector2d_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::dotproduct",(Tcl_ObjCmdProc *)TclCmd_vector2d_dotproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::.",(Tcl_ObjCmdProc *)TclCmd_vector2d_dotproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::crossproduct",(Tcl_ObjCmdProc *)TclCmd_vector2d_crossproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::x",(Tcl_ObjCmdProc *)TclCmd_vector2d_crossproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::rightof",(Tcl_ObjCmdProc *)TclCmd_vector2d_rightof,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::rotate_and_size",(Tcl_ObjCmdProc *)TclCmd_vector2d_rotate_and_size,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::scale",(Tcl_ObjCmdProc *)TclCmd_vector2d_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::translate_and_zoom",(Tcl_ObjCmdProc *)TclCmd_vector2d_translate_and_zoom,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::point_on_segment",(Tcl_ObjCmdProc *)TclCmd_vector2d_point_on_segment,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::point_on_segment",(Tcl_ObjCmdProc *)TclCmd_vector2d_point_on_segment,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::line_circle_intersect",(Tcl_ObjCmdProc *)TclCmd_vector2d_line_circle_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::line_circle_intersect",(Tcl_ObjCmdProc *)TclCmd_vector2d_line_circle_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::line_intersect",(Tcl_ObjCmdProc *)TclCmd_vector2d_line_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::line_intersect",(Tcl_ObjCmdProc *)TclCmd_vector2d_line_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::line_overlap",(Tcl_ObjCmdProc *)TclCmd_vector2d_line_overlap,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::line_overlap",(Tcl_ObjCmdProc *)TclCmd_vector2d_line_overlap,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector2d::colinear",(Tcl_ObjCmdProc *)TclCmd_vector2d_colinear,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::colinear",(Tcl_ObjCmdProc *)TclCmd_vector2d_colinear,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vector2d",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector2d.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector3d.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vector3d",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::vector3d", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::vector3d::compare",(Tcl_ObjCmdProc *)TclCmd_vector3d_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::=",(Tcl_ObjCmdProc *)TclCmd_vector3d_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::add",(Tcl_ObjCmdProc *)TclCmd_vector3d_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::+",(Tcl_ObjCmdProc *)TclCmd_vector3d_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::subtract",(Tcl_ObjCmdProc *)TclCmd_vector3d_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::-",(Tcl_ObjCmdProc *)TclCmd_vector3d_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::orthagonal",(Tcl_ObjCmdProc *)TclCmd_vector3d_orthagonal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::distance",(Tcl_ObjCmdProc *)TclCmd_vector3d_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vector3d::distanceSq",(Tcl_ObjCmdProc *)TclCmd_vector3d_distanceSq,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vector3d",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vector3d.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorn.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vectorN",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::vectorN", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::vectorN::length",(Tcl_ObjCmdProc *)TclCmd_vectorN_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorN::distance",(Tcl_ObjCmdProc *)TclCmd_vectorN_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::distance",(Tcl_ObjCmdProc *)TclCmd_vectorN_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorN::scale",(Tcl_ObjCmdProc *)TclCmd_vectorN_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorN::scalevar",(Tcl_ObjCmdProc *)TclCmd_vectorN_scalevar,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vectorN",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorn.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxy.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vectorxy",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::vectorxy", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::vectorxy::compare",(Tcl_ObjCmdProc *)TclCmd_vectorxy_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::=",(Tcl_ObjCmdProc *)TclCmd_vectorxy_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::add",(Tcl_ObjCmdProc *)TclCmd_vectorxy_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::+",(Tcl_ObjCmdProc *)TclCmd_vectorxy_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::subtract",(Tcl_ObjCmdProc *)TclCmd_vectorxy_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::-",(Tcl_ObjCmdProc *)TclCmd_vectorxy_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::midpoint",(Tcl_ObjCmdProc *)TclCmd_vectorxy_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::-",(Tcl_ObjCmdProc *)TclCmd_vectorxy_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::add_stream",(Tcl_ObjCmdProc *)TclCmd_vectorxy_add_stream,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::angle",(Tcl_ObjCmdProc *)TclCmd_vectorxy_angle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::create",(Tcl_ObjCmdProc *)TclCmd_vectorxy_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::toint",(Tcl_ObjCmdProc *)TclCmd_vectorxy_toint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::crossproduct",(Tcl_ObjCmdProc *)TclCmd_vectorxy_crossproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::x",(Tcl_ObjCmdProc *)TclCmd_vectorxy_crossproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::distance",(Tcl_ObjCmdProc *)TclCmd_vectorxy_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::length",(Tcl_ObjCmdProc *)TclCmd_vectorxy_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::normalize",(Tcl_ObjCmdProc *)TclCmd_vectorxy_normalize,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::dotproduct",(Tcl_ObjCmdProc *)TclCmd_vectorxy_dotproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::.",(Tcl_ObjCmdProc *)TclCmd_vectorxy_dotproduct,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::rightof",(Tcl_ObjCmdProc *)TclCmd_vectorxy_rightof,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::rotate_and_size",(Tcl_ObjCmdProc *)TclCmd_vectorxy_rotate_and_size,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::scale",(Tcl_ObjCmdProc *)TclCmd_vectorxy_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::translate_and_zoom",(Tcl_ObjCmdProc *)TclCmd_vectorxy_translate_and_zoom,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxy::flatten",(Tcl_ObjCmdProc *)TclCmd_vectorxy_flatten,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vectorxy",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxy.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxyz.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vectorxyz",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::vectorxyz", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::vectorxyz::scale",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_scale,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::zero",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_zero,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::compare",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::=",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::polygon_normal_compare",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_polygon_normal_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::create",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::toint",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_toint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::add",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::+",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_add,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::add_inplace",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_add_inplace,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::++",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_add_inplace,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::orthagonal",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_orthagonal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::subtract",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::-",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_subtract,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::midpoint",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::cross_product",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_cross_product,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::x",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_cross_product,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::dot_product",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_dot_product,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::.",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_dot_product,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::transform",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_transform,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::length",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::mangitude",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::xyz_length",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::distance",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::xyz_distance",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::distanceSq",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_distanceSq,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::xyz_distance_sq",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_distanceSq,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::length_inv_sqr",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_length_inv_sqr,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::mangitude_inv_sqr",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_length_inv_sqr,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::xyz_mag_inv_sq",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_length_inv_sqr,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::normalize",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_normalize,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::point_on_segment",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_point_on_segment,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::point_on_segment_x",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_point_on_segment_x,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::axis_of_normal",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_axis_of_normal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::bend_direction",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_bend_direction,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::rightof",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_bend_direction,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::angle_three_points",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_angle_three_points,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::colinear",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_colinear,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::coplaner",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_coplaner,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::linelinecoincident_int",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_linelinecoincident_int,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::linelinecoincident",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_linelinecoincident,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::linelineintersect",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_linelineintersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::linelineintersect_distance",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_linelineintersect_distance,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::sizeof",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_sizeof,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::closest_point_on_segment",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_closest_point_on_segment,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::point_in_triangle",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_point_in_triangle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::triangle_line_intersect",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_triangle_line_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::line_sphere_intersect_length",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_line_sphere_intersect_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::line_sphere_intersect_length",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_line_sphere_intersect_length,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::line_sphere_intersect_area",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_line_sphere_intersect_area,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::line_sphere_intersect_area",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_line_sphere_intersect_area,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::line_sphere_intersect",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_line_sphere_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::line_sphere_intersect",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_line_sphere_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::polygon_normal",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_polygon_normal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::polygon_center",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_polygon_center,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::vectorxyz::flatten",(Tcl_ObjCmdProc *)TclCmd_vectorxyz_flatten,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::vectorxyz",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/vectorxyz.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/affine/cmatrixforms.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::matrix",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::matrix", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::matrix::to_aabb_xyz",(Tcl_ObjCmdProc *)TclCmd_matrix_to_aabb_xyz,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_affine",(Tcl_ObjCmdProc *)TclCmd_matrix_to_affine,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_bbox_xy",(Tcl_ObjCmdProc *)TclCmd_matrix_to_bbox_xy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_cylindrical",(Tcl_ObjCmdProc *)TclCmd_matrix_to_cylindrical,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_euler",(Tcl_ObjCmdProc *)TclCmd_matrix_to_euler,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_heading",(Tcl_ObjCmdProc *)TclCmd_matrix_to_heading,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_mat2",(Tcl_ObjCmdProc *)TclCmd_matrix_to_mat2,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_mat3",(Tcl_ObjCmdProc *)TclCmd_matrix_to_mat3,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_mat4",(Tcl_ObjCmdProc *)TclCmd_matrix_to_mat4,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_null",(Tcl_ObjCmdProc *)TclCmd_matrix_to_null,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_polar",(Tcl_ObjCmdProc *)TclCmd_matrix_to_polar,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_quaternion",(Tcl_ObjCmdProc *)TclCmd_matrix_to_quaternion,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_scaler",(Tcl_ObjCmdProc *)TclCmd_matrix_to_scaler,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_spherical",(Tcl_ObjCmdProc *)TclCmd_matrix_to_spherical,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_unknown",(Tcl_ObjCmdProc *)TclCmd_matrix_to_unknown,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_vector_xy",(Tcl_ObjCmdProc *)TclCmd_matrix_to_vector_xy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_vector_xyz",(Tcl_ObjCmdProc *)TclCmd_matrix_to_vector_xyz,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::matrix::to_vector_xyzw",(Tcl_ObjCmdProc *)TclCmd_matrix_to_vector_xyzw,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::matrix",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/affine/cmatrixforms.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/fuzzy/fuzzy.tcl */
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::to_fuzzy",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_to_fuzzy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::double_to_fuzzy",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_to_fuzzy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::fuzzy_abs",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_abs,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::fuzzy_abs",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_abs,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::fuzzy_compare",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::fuzzy_compare",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::fuzzy_is_zero",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_is_zero,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::fuzzy_is_zero",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_is_zero,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::fuzzy_gt_zero",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_gt_zero,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::fuzzy_gt_zero",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_gt_zero,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::tcl::mathfunc::fuzzy_epsilon",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_epsilon,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::odiemath::fuzzy_epsilon",(Tcl_ObjCmdProc *)TclCmd_tcl_mathfunc_fuzzy_epsilon,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/fuzzy/fuzzy.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/triangulate.tcl */
- Tcl_CreateObjCommand(interp, "convex_subpolygons", convexSubpolyCmd, 0, 0);
- Tcl_CreateObjCommand(interp, "convex_subpolygons_new", convexNewSubpolyCmd, 0, 0);
- Tcl_CreateObjCommand(interp,"::triag_test_rightof",(Tcl_ObjCmdProc *)TclCmd_triag_test_rightof,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::triag_test_dotprod",(Tcl_ObjCmdProc *)TclCmd_triag_test_dotprod,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::triag_test_angle",(Tcl_ObjCmdProc *)TclCmd_triag_test_angle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::triag_test_ideal",(Tcl_ObjCmdProc *)TclCmd_triag_test_ideal,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/triangulate.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygon.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::polygon",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::polygon", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::polygon::create",(Tcl_ObjCmdProc *)TclCmd_polygon_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::compare",(Tcl_ObjCmdProc *)TclCmd_polygon_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::simplify",(Tcl_ObjCmdProc *)TclCmd_polygon_simplify,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::area",(Tcl_ObjCmdProc *)TclCmd_polygon_area,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::bbox",(Tcl_ObjCmdProc *)TclCmd_polygon_bbox,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::info",(Tcl_ObjCmdProc *)TclCmd_polygon_info,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::intersect",(Tcl_ObjCmdProc *)TclCmd_polygon_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::within",(Tcl_ObjCmdProc *)TclCmd_polygon_within,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::center",(Tcl_ObjCmdProc *)TclCmd_polygon_center,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::canvascoords",(Tcl_ObjCmdProc *)TclCmd_polygon_canvascoords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::coords",(Tcl_ObjCmdProc *)TclCmd_polygon_coords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::xycoords",(Tcl_ObjCmdProc *)TclCmd_polygon_xycoords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::edges",(Tcl_ObjCmdProc *)TclCmd_polygon_edges,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::bend",(Tcl_ObjCmdProc *)TclCmd_polygon_bend,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::is_convex",(Tcl_ObjCmdProc *)TclCmd_polygon_is_convex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::segments",(Tcl_ObjCmdProc *)TclCmd_polygon_segments,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::rectangle",(Tcl_ObjCmdProc *)TclCmd_polygon_rectangle,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::vector_place",(Tcl_ObjCmdProc *)TclCmd_polygon_vector_place,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::hexagon",(Tcl_ObjCmdProc *)TclCmd_polygon_hexagon,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::poly_place",(Tcl_ObjCmdProc *)TclCmd_polygon_poly_place,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::drawobj_orientation",(Tcl_ObjCmdProc *)TclCmd_polygon_drawobj_orientation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::corners",(Tcl_ObjCmdProc *)TclCmd_polygon_corners,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::hexgrid_location",(Tcl_ObjCmdProc *)TclCmd_polygon_hexgrid_location,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::hexgrid_create",(Tcl_ObjCmdProc *)TclCmd_polygon_hexgrid_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygon::squaregrid_create",(Tcl_ObjCmdProc *)TclCmd_polygon_squaregrid_create,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::polygon",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygon.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygonxyz.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::polygonxyz",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::polygonxyz", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::polygonxyz::info",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_info,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::create",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::createxy",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_createxy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::simplify",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_simplify,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::id",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_id,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::area",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_area,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::bbox",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_bbox,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::bend",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_bend,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::center",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_center,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::is_2d",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_is_2d,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::is_convex",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_is_convex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::normal",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_normal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::nVertex",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_nVertex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::radius",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_radius,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::rotation",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_rotation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::rotation_inv",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_rotation_inv,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::axis_of_normal",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_axis_of_normal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::canvascoords",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_canvascoords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::coords",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_coords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::intcoordsxy",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_intcoordsxy,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::intcoords",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_intcoords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::edges",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_edges,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::triangles",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_triangles,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::uvcoords",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_uvcoords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::xycoords",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_xycoords,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::compare",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_compare,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::coplaner",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_coplaner,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::flipped",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_flipped,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::side",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_side,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::intersect_test",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_intersect_test,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::intersect_test_uv",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_intersect_test_uv,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::intersect",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::intersect_uv",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_intersect_uv,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::points_within",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_points_within,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::within",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_within,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::polygonxyz::within_set",(Tcl_ObjCmdProc *)TclCmd_polygonxyz_within_set,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::polygonxyz",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/polygonxyz.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/segset.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::segset",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::segset", NULL, NULL);
- }
- }
- if (SegmentSet_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::segset",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/segset.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/shapes.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::shapes",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::shapes", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::shapes::corners",(Tcl_ObjCmdProc *)TclCmd_shapes_corners,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::drawobj_orientation",(Tcl_ObjCmdProc *)TclCmd_shapes_drawobj_orientation,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::poly_hex",(Tcl_ObjCmdProc *)TclCmd_shapes_poly_hex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::poly_place",(Tcl_ObjCmdProc *)TclCmd_shapes_poly_place,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::polygon_to_vectors",(Tcl_ObjCmdProc *)TclCmd_shapes_polygon_to_vectors,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::rectangle_as_polygon",(Tcl_ObjCmdProc *)TclCmd_shapes_rectangle_as_polygon,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::rectangle_as_vectors",(Tcl_ObjCmdProc *)TclCmd_shapes_rectangle_as_vectors,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::vector_place",(Tcl_ObjCmdProc *)TclCmd_shapes_vector_place,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::hexagon",(Tcl_ObjCmdProc *)TclCmd_shapes_hexagon,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::shapes::canvas",(Tcl_ObjCmdProc *)TclCmd_shapes_canvas,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::shapes",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/shapes.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/plotter.tcl */
- if (Plotter_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/plotter.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/slicer.tcl */
- if (Slicer_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/slicer.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/wallset.tcl */
- if (Wallset_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/wallset.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/faceset.tcl */
- if (PolygonHull_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/geometry/faceset.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/listcmd/listcmd.tcl */
- Tcl_CreateObjCommand(interp,"::get",(Tcl_ObjCmdProc *)TclCmd_get,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::list_to_int",(Tcl_ObjCmdProc *)TclCmd_list_to_int,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::ladd",(Tcl_ObjCmdProc *)TclCmd_ladd,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::ldelete",(Tcl_ObjCmdProc *)TclCmd_ldelete,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/listcmd/listcmd.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/logicset/logicset.tcl */
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::logicset",NULL,TCL_NAMESPACE_ONLY);
- if(!modPtr) {
- modPtr = Tcl_CreateNamespace(interp, "::logicset", NULL, NULL);
- }
- }
- Tcl_CreateObjCommand(interp,"::logicset::union",(Tcl_ObjCmdProc *)TclCmd_logicset_union,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::add",(Tcl_ObjCmdProc *)TclCmd_logicset_union,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::create",(Tcl_ObjCmdProc *)TclCmd_logicset_create,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::contains",(Tcl_ObjCmdProc *)TclCmd_logicset_contains,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::empty",(Tcl_ObjCmdProc *)TclCmd_logicset_empty,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::expr_and",(Tcl_ObjCmdProc *)TclCmd_logicset_expr_and,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::expr_or",(Tcl_ObjCmdProc *)TclCmd_logicset_expr_or,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::product_intersect",(Tcl_ObjCmdProc *)TclCmd_logicset_product_intersect,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::product_union",(Tcl_ObjCmdProc *)TclCmd_logicset_product_union,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::product_xor",(Tcl_ObjCmdProc *)TclCmd_logicset_product_xor,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::product_missing",(Tcl_ObjCmdProc *)TclCmd_logicset_product_missing,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::logicset::remove",(Tcl_ObjCmdProc *)TclCmd_logicset_remove,NULL,NULL);
- {
- Tcl_Namespace *modPtr;
- modPtr=Tcl_FindNamespace(interp,"::logicset",NULL,TCL_NAMESPACE_ONLY);
- Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX);
- Tcl_Export(interp, modPtr, "[a-z]*", 1);
- }
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/logicset/logicset.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/literal/literal.tcl */
- static int constant_once = 1;
- if( constant_once ){
- int i;
- constant_once = 0;
- Tcl_InitHashTable(&OdieLiteralStringTable,TCL_STRING_KEYS);
- OdieStatic[ODIE_STATIC_NULL]=Tcl_NewObj();
- Tcl_IncrRefCount(OdieStatic[ODIE_STATIC_NULL]);
- Odie_constant_inject(OdieStatic[ODIE_STATIC_NULL]);
- OdieStatic[ODIE_STATIC_ZERO] = Tcl_NewBooleanObj(0);
- Tcl_IncrRefCount(OdieStatic[ODIE_STATIC_ZERO]);
- Odie_constant_inject(OdieStatic[ODIE_STATIC_ZERO]);
- OdieStatic[ODIE_STATIC_ONE] = Tcl_NewBooleanObj(1);
- Tcl_IncrRefCount(OdieStatic[ODIE_STATIC_ONE]);
- Odie_constant_inject(OdieStatic[ODIE_STATIC_ONE]);
- for(i=2;i<10;i++) {
- int idx=ODIE_STATIC_ZERO+i;
- OdieStatic[idx] = Tcl_NewIntObj(i);
- Tcl_IncrRefCount(OdieStatic[idx]);
- Odie_constant_inject(OdieStatic[idx]);
- }
- OdieStatic[ODIE_STATIC_FZERO] = Tcl_NewDoubleObj(0.0);
- Tcl_IncrRefCount(OdieStatic[ODIE_STATIC_FZERO]);
- Odie_constant_inject(OdieStatic[ODIE_STATIC_FZERO]);
- OdieStatic[ODIE_STATIC_NEG1] = Tcl_NewIntObj(-1);
- Tcl_IncrRefCount(OdieStatic[ODIE_STATIC_NEG1]);
- Odie_constant_inject(OdieStatic[ODIE_STATIC_NEG1]);
- }
- Tcl_CreateObjCommand(interp,"::literal",(Tcl_ObjCmdProc *)TclCmd_literal,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::literal_dump",(Tcl_ObjCmdProc *)TclCmd_literal_dump,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::literal_stats",(Tcl_ObjCmdProc *)TclCmd_literal_stats,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::constant_string",(Tcl_ObjCmdProc *)TclCmd_constant_string,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/literal/literal.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/location.tcl */
- Tcl_CreateObjCommand(interp,"::location::grid_square",(Tcl_ObjCmdProc *)TclCmd_location_grid_square,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::gridhash_square",(Tcl_ObjCmdProc *)TclCmd_location_gridhash_square,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::location_gridhash",(Tcl_ObjCmdProc *)TclCmd_location_location_gridhash,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::grid_hex",(Tcl_ObjCmdProc *)TclCmd_location_grid_hex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::gridhash_hex",(Tcl_ObjCmdProc *)TclCmd_location_gridhash_hex,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::gridhash_adjacent",(Tcl_ObjCmdProc *)TclCmd_location_gridhash_adjacent,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::object",(Tcl_ObjCmdProc *)TclCmd_location_object,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::midpoint",(Tcl_ObjCmdProc *)TclCmd_location_midpoint,NULL,NULL);
- Tcl_CreateObjCommand(interp,"::location::match",(Tcl_ObjCmdProc *)TclCmd_location_match,NULL,NULL);
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/location.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl */
- if (Simulator_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/entity.tcl */
- if (OOEntity_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/entity.tcl */
- /* BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simtype.tcl */
- if (SimType_OO_Init(interp) != TCL_OK) return TCL_ERROR;
- /* END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simtype.tcl */
- if(interp) {
- if(Tcl_Eval(interp,
- "\n" \
- "# BEGIN /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl\n" \
- "if {[info command ::simulator] eq {}} {\n" \
- " ::odielib::simulator create ::simulator\n" \
- "}\n" \
- "if {[info command ::entity] eq {}} {\n" \
- " ::odielib::entity create ::entity ::simulator\n" \
- "}\n" \
- "if {[info command ::simtype] eq {}} {\n" \
- " ::odielib::simtype create ::simtype ::simulator\n" \
- "}\n" \
- "# END /Users/seandeelywoods/build/odie/odielib/cmodules/typespec/simulator.tcl\n" \
- "\n" )) return TCL_ERROR;
- }
- if (Tcl_PkgProvide(interp, "odielibc" , "2.3" )) return TCL_ERROR;
- return TCL_OK;
- }