00001
00002
00003
00004 #ifndef NodeArray_H
00005 #define NodeArray_H
00006
00007 #include "util.h"
00008 #include "point3d.h"
00009 #include "node.h"
00010
00011 #include "reallocablearray.h"
00012 #include "geometryreplicator.h"
00013 #include "matrix.h"
00014 #include <string.h>
00015 #include <stdio.h>
00016
00017 class Node;
00018 class EdgeArray;
00019 class FaceArray;
00020 class Object;
00021 typedef ReallocableArray<int> sbb_t;
00022
00023 typedef enum {grab, pierce, collide} Constraint_type;
00024 typedef enum {FULL, REL, ABS, NONE} Damping_type;
00025
00026
00027 typedef struct {
00028 int index;
00029 Constraint_type type;
00030 Node *n;
00031 int whichpierce;
00032 Edge *e;
00033 double w0, w1;
00034 int whichcollide;
00035 } Thread_constraint;
00036
00037
00038
00039 #define TORSION_FORCE 0
00040 typedef enum{ RIGHT, LEFT, FRONT, BACK, UP, DOWN } wall_pos;
00041 #define RIGIDNEEDLE 10 // for use only with needle/thread
00042 Point3D ApplyMatrix(Point3D e1, Point3D e2, Point3D e3, Point3D v);
00043
00044 class NodeArray
00045 {
00046 private:
00047 int numnodes, maxnodes;
00048 Node* *nodes;
00049 Node* *orderedNodes;
00050 int highlevel;
00051 int highnode;
00052 char nodefilename[MAXLINE];
00053 Point3D min, max;
00054 Point3D init_min, init_max;
00055 Point3D center;
00056 Point3D cg;
00057
00058 Point3D center_bounding_box;
00059 double radius;
00060
00061 Point3D dimension;
00062 sbb_t sbb[4][4][4];
00063 double convergence_factor;
00064 double U[3][3];
00065 double sig[3];
00066
00067
00068 EdgeArray* edgearray_p;
00069 Object* object_p;
00070
00071 Damping_type damping_type;
00072
00073
00074 static void updateNodes_thread(void* in);
00075 static void findPositionThreads(int,int,void*);
00076 static void findVelocityThreads(int,int,void*);
00077 static void findForceThreads(int,int,void*);
00078
00079 static void findMidpointRKThreads(int thread_index, int max_threads,
00080 void* data);
00081 static void findFinalRK2Threads(int thread_index, int max_threads,
00082 void* data);
00083 static void findfindMidpoint2RK4Threads(int thread_index, int max_threads,
00084 void* data);
00085 static void findGuessRK4Threads(int thread_index, int max_threads,
00086 void* data);
00087 static void findFinalRK4Threads(int thread_index, int max_threads,
00088 void* data);
00089 static void forceDisplacementThreads(int thread_index, int max_threads,
00090 void* data);
00091 static void FSAThreads(int thread_index, int max_threads, void* data);
00092
00093 public:
00094 NodeArray(Object* object_p_in);
00095 ~NodeArray();
00096
00097 static const char* rcsid;
00098
00099 void Init(EdgeArray* edgearray_p_in);
00100 void reset(void);
00101 int getNumNodes(void);
00102 Object* getObject();
00103 EdgeArray* getEdgeArray();
00104
00105
00106 static int debug;
00107 int orderedNodesFlag;
00108
00109
00110 void computeStats();
00111 void getBoundingBox(Point3D* min_p, Point3D* max_p);
00112 void getInitialBoundingBox(Point3D* imin_p, Point3D* imax_p);
00113 double getRadius();
00114
00115 Point3D getDimension();
00116 Point3D getCenter();
00117 Point3D getCenterOfGravity();
00118
00119 Point3D getCenterOfBoundingBox();
00120 void spread2(double kx, double ky, double kz) ;
00121
00122 void rotate90(int axis = 0) { rotate(axis);}
00123 void rotate(int axis = 0, double t = PI/2);
00124 void spread(double kx, double ky, double kz);
00125 void translate(double kx, double ky, double kz);
00126 Point3D getHorizontalVector();
00127 Point3D getVerticalVector();
00128 void refresh();
00129 void pivote(wall_pos dir);
00130 void stretch(wall_pos dir);
00131 void twist(wall_pos dir);
00132 void PrincipalAxes();
00133 void getUmatrix(double newU[3][3]);
00134
00135
00136 void setNodeFilename(char *s);
00137 int getMeshNodeData(FILE *meshfile);
00138 int getSMFNodeData(FILE *meshfile);
00139 int getOBJNodeData(FILE *meshfile);
00140 int getNodeData(void);
00141 int getAmiraNodeData(FILE *meshfile, int numnodes_given);
00142
00143 void SaveMeshNodeData(ostream& os);
00144 void SaveSMFNodeData(ostream& os);
00145 void SaveVRMLNodeData(ostream& os);
00146 void SaveAmiraNodeData(ostream& os);
00147 void SaveVRMLNormalData(ostream& os);
00148
00149
00150 Node *getNode(int i);
00151 int getIndex(Node* n);
00152 void CacheIndices();
00153 friend ostream& operator<<(ostream & out, const NodeArray &na);
00154
00155
00156 void allocateNodes(int max_num_nodes);
00157 int addNode(Point3D p);
00158
00159
00160 void DrawNodes();
00161 void drawlabels(float offset);
00162 void drawnormals();
00163 void drawinitial();
00164 void drawtienodes();
00165 int updateNodes(void);
00166 int updateNodesRigid(void);
00167
00168 void updateArticulateEdge(void);
00169 double findThreadSlack(int start_node, int end_node);
00170 double findMaxStretch(int start_node, int end_node);
00171 int whichConstraint(int i, Thread_constraint *constraints,
00172 int numconstraints);
00173 void updateArticulateSections(Thread_constraint *constraints,
00174 int numconstraints);
00175 void updateArticulateUpOrDown(int start_node, int end_node, int average=0);
00176 void updateThread(void);
00177 void FollowTheLeader(int start_node, int end_node, int average=0);
00178
00179 void moveNodesOfPart(int part, Point3D motion_vector, int absolute=0);
00180 void xformNodesOfParts(ReallocableArray<Matrix> parts_matrices,
00181 ReallocableArray<Point3D> prerot_trans,
00182 ReallocableArray<Point3D> postrot_trans);
00183 void xformNodesOfPart(int part, Matrix matrix, Point3D offset,
00184 Point3D new_origin);
00185 void resetInitialPosition();
00186 void setToInitialPosition();
00187 void setFext(Point3D force);
00188 void setVelocityDampConstants(double value);
00189 void setMasses(double value);
00190 void processCollisions(NodeArray* na);
00191 void resetCollisions();
00192 void printInfo(void);
00193 void computeInitialEdgeSums(void);
00194 void interpolateNormals(void);
00195 void interpolateTetraNormals(void);
00196 double getEnergy(void);
00197 double findError(void);
00198 void DeleteNode(Node* n);
00199 void DeleteNode(int index);
00200 void EraseNode(Node* n, Node *adjacents[]);
00201 void DeleteAllNodes();
00202 void computeTextureCoords(Node::texture_coord_type textype);
00203 void moveTexture(Point3D translation, Point3D scaling);
00204 void SanityCheck(Object* o_p);
00205 double CumulativeDistanceToSurface(FaceArray* fa_p);
00206 void multiplyNodes(double value);
00207 void ScaleByNormal(double value);
00208 int findClosestNode(Point3D pt);
00209 int findCollisionNode(Point3D pt);
00210 double findClosestNodesBetweenNodeArrays(NodeArray* other_na,
00211 Node** our_node_p, Node** other_node_p);
00212 void TieNodesToClosestInNodeArray(NodeArray* other_na);
00213 void MakeEdgeToClosestInNodeArray(NodeArray* other_na);
00214 void redistributeMass();
00215 void RedistributeSubset();
00216 void RedistributeTetraSubset();
00217 void RedistributeSurfaceSubset();
00218
00219
00220
00221 int getNumDifferentColors();
00222 int getNumNodesOfColor(int color);
00223 int VertexColor();
00224 void OrderNodes(Node *n, int keepCurrentGrabs = 1);
00225 void ResetColors(int color);
00226 void ResetLevels(int level);
00227 void SplitColor(Face* splitting_face);
00228 void DeleteNodesOfColor(int color);
00229 void FixNodesOfColor(int color);
00230 void getColorBoundingBox(int color, Point3D* min_p, Point3D* max_p);
00231 void ColorNodesWithinBoundingBox(Point3D min, Point3D max, int color);
00232 int SpreadOutColor();
00233 int CompressDuplicateNodes(double dist);
00234
00235 void setDampingType(int dtype);
00236 int getDampingType();
00237
00238 void GeometryReplicate(GeometryReplicator* gr);
00239 };
00240
00241 inline int NodeArray::getNumNodes(void)
00242 {return numnodes;}
00243
00244 inline void NodeArray::getBoundingBox(Point3D* min_p, Point3D* max_p)
00245 { *min_p = min, *max_p = max; }
00246
00247 inline void NodeArray::getInitialBoundingBox(Point3D* imin_p, Point3D* imax_p)
00248 { *imin_p = init_min, *imax_p = init_max; }
00249
00250 inline double NodeArray::getRadius()
00251 { return(radius); }
00252
00253
00254 inline Point3D NodeArray::getDimension()
00255
00256 { return dimension; }
00257
00258
00259 inline Point3D NodeArray::getCenter()
00260 { return(center); }
00261
00262 inline Point3D NodeArray::getCenterOfGravity()
00263 { return(cg); }
00264
00265
00266 inline Point3D NodeArray::getCenterOfBoundingBox()
00267
00268 { return center_bounding_box; }
00269
00270
00271 inline void NodeArray::setNodeFilename(char *s)
00272 { strcpy(nodefilename, s); }
00273
00274 inline Node* NodeArray::getNode(int i)
00275 { return (nodes[i]); }
00276
00277 inline Object* NodeArray::getObject()
00278 { return (object_p); }
00279
00280 inline EdgeArray* NodeArray::getEdgeArray()
00281 { return (edgearray_p); }
00282
00283 inline void NodeArray::setDampingType(int dtype)
00284 { damping_type = Damping_type(dtype); }
00285
00286 inline int NodeArray::getDampingType()
00287 { return (damping_type); }
00288
00289 inline void NodeArray::getUmatrix(double newU[3][3])
00290 { for(int i=0;i<3;i++)for(int j=0;j<3;j++)newU[i][j]=U[i][j];}
00291
00292 #endif