00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Cristin Barghiel 00008 * Side Effects Software Inc. 00009 * 477 Richmond Street West 00010 * Toronto, Ontario 00011 * Canada M5V 3E7 00012 * 416-504-9876 00013 * 00014 * NAME: Geometry Library (C++) 00015 * 00016 * COMMENTS: Paste surface class. 00017 * 00018 */ 00019 00020 #ifndef __GEO_PasteSurf_h__ 00021 #define __GEO_PasteSurf_h__ 00022 00023 #include "GEO_API.h" 00024 #include <UT/UT_RefMatrix.h> 00025 #include <UT/UT_Vector2.h> 00026 #include <GP/GP_Domain.h> 00027 #include "GEO_PasteVertex.h" 00028 00029 class UT_Vector4; 00030 class GB_AttributeData; 00031 class GB_FloatOffsets; 00032 class GP_NodeList; 00033 class GEO_Vertex; 00034 class GEO_AttributeHandleList; 00035 class GEO_TPSurf; 00036 class GEO_PasteSurfDAG; 00037 00038 00039 class GEO_API GEO_PasteSurf : public GP_Domain 00040 { 00041 friend class GEO_PasteSurfDAG; 00042 00043 public: 00044 // Class c-tors and d-tor 00045 GEO_PasteSurf(void); 00046 GEO_PasteSurf(GEO_TPSurf &tpsurf, const GP_XformHandle &xform, 00047 int pasteup = 1, float height = 0); 00048 GEO_PasteSurf(const GEO_PasteSurf &d); 00049 virtual ~GEO_PasteSurf(void); 00050 00051 // Produce a brand new copy of ourselves. Must free it yourself. 00052 // Does not copy the spline surface, just its primitive index! 00053 virtual GP_Node *copy(void) const; 00054 00055 // Create a a brand new object of the same type as us just using the 00056 // default c-tor. 00057 virtual GP_Node *newSpecies(void) const; 00058 00059 // I/O functions returning 0 if OK and -1 otherwise. 00060 virtual int save(ostream &os, int binary = 0) const; 00061 virtual bool load(UT_IStream &is); 00062 00063 // Return a decreasing-order list of would-be parents listed in decreasing 00064 // order in a stack of nodes. 00065 virtual void findParents(GP_NodeList &stack, GP_NodeList &parents); 00066 virtual void findParent (GP_Domain &parent); 00067 00068 // Spawn a child and link it to us, assign its frames accordingly, update 00069 // its vertices, set its parent and base, etc. Return that domain if 00070 // everything is successful, else 0. The child in the domain area defined 00071 // by brect, and the ub/vb stuff are belt reinforcements. 00072 virtual GP_Domain *spawn(const UT_BoundingRect &brect, 00073 float ubwidth = 0, float vbwidth = 0, 00074 int ubdivs = 2, int vbdivs = 2, 00075 int newkey = 0); 00076 00077 // Evaluate at a world domain point and return 0 if successful, else -1: 00078 bool evaluate(fpreal worldu, fpreal worldv, 00079 GEO_Vertex &result, 00080 GEO_AttributeHandleList &hlist, 00081 unsigned du = 0, unsigned dv = 0) const; 00082 int evaluate(float worldu, float worldv, UT_Vector4 &pos, 00083 unsigned du = 0, unsigned dv = 0) const; 00084 int evaluateWAttrib(float worldu, float worldv, 00085 UT_Vector4 &pos, GB_AttributeData &adata, 00086 const GB_FloatOffsets &foffsets, 00087 unsigned du = 0, unsigned dv = 0) const; 00088 00089 // Make this surface's CVs independent of any base surfaces and reset the 00090 // base surface pointers to point at myself: 00091 void independentVertices(int preserve_shape = 1); 00092 00093 // Translate all the CVs by an equal amount in world space: 00094 void translateVertices(const UT_Vector3 &delta); 00095 00096 // Update the frame origins by translating them because the CVs of the 00097 // spline surface have been translated by this amount too. 00098 void updateTranslation(const UT_Vector3 &delta); 00099 00100 // Build the local frames using the current base surfaces, then apply 00101 // the displacements to compute the world image. This is likely to 00102 // change the contents of the GEO_Points. 00103 void updateVertices(void); 00104 00105 // Some vertices (or all) have changed, so reverse engineer our 00106 // displacements from the CVs of the spline surface. In other words, 00107 // given the local frames and the GEO_Points, build our displacements. 00108 void updateDisplacements(int keepframes = 1); 00109 00110 // Indicate that a CV has changed. 00111 // These methods don't touch mySurf in any way, so make sure you do it 00112 // yourself before calling us. Also, we don't flag the surface cache, and 00113 // we don't update the hierarchy pasted on us. Better change all you have 00114 // to change, then updateDescendents() from the DAG class. 00115 // Another WARNING: we don't check if r and c are within bounds! 00116 void updateDisplacement(int r, int c); 00117 void updateDisplacement(int r, int c, GEO_Point &ppt); 00118 00119 // Recompute the vertices and the domain of the root surface such that 00120 // the domain fits the root tightly, and the CVs are displaced from 00121 // the Grevilles as tightly as possible. 00122 void optimizeDisplacements(int update = 1); 00123 00124 // Set the bases from a single parent. Be careful with this method. 00125 void setBases(GEO_PasteSurf *base = 0); 00126 00127 // A much cheaper version than modifyBasis(). To be called when the 00128 // original basis has been remapped _affinely_ to another range, e.g. 00129 // using GEO_TPSurf::mapU/VBasis(). The result should leave everything 00130 // unchanged, including displacements, world image, base surfaces, etc. 00131 // Don't even think of using it when reparameterizing the surface or 00132 // refining it. 00133 void affineBasis(void); 00134 00135 // Compute the texture coordinates either uniformly of chord length. If 00136 // the offset if negative, the methods find it and create the attribute 00137 // if necessary. If ptattrib is 1 we deal with points, else with vertices. 00138 // Return the texture offset or -1 if problems. 00139 int rowColTexture (int txtoff = -1, int ptattrib = 1); 00140 int uniformTexture (int txtoff = -1, int ptattrib = 1); 00141 int grevilleTexture(int txtoff = -1, int ptattrib = 1); 00142 int chordLenTexture(int txtoff = -1, int ptattrib = 1); 00143 00144 // Trim the underlying base(s): 00145 void trimUnder(float scale = 1.0f, int keepoutside = 1); 00146 00147 // Query or set the height, which is just an offset of the CV displacement: 00148 float height(void) const { return myHeight; } 00149 void height(float h); 00150 00151 // Reset the spline surface pointer. If mutual, then we reset the 00152 // surface's pointer to us as well. Use with care. 00153 // Pardon the choice of names :-) 00154 void sterilize(int mutual = 1); 00155 void pregnant (GEO_TPSurf &s, int mutual=1, int rebuild=1); 00156 00157 // Query or set the paste direction flag, and then possibly update the 00158 // world image. Normally you want the image to update: 00159 int pastedUp (void) const { return myPasteUp; } 00160 void pasteUp (int updt=1) { flipPaste(1, updt); } 00161 void pasteDown(int updt=1) { flipPaste(0, updt); } 00162 00163 // Cautious handles to our frame and surface: 00164 const GP_Frame &frame (void) const { return frames()->root(); } 00165 const GEO_TPSurf &surface(void) const { return *mySurf; } 00166 00167 // Determine if we are associated with a surface: 00168 int hasSurface(void) const { return (mySurf) ? 1 : 0; } 00169 00170 GEO_PasteSurfDAG *hierarchy(void) const; // return dag(); 00171 00172 // Index of spline primitive we should use as mySurf. To be used ONLY 00173 // for loading purposes. myNum is never updated afterwards. 00174 int primNumber(void) const { return myNum; } 00175 00176 00177 protected: 00178 // Copy the in nodes from a pool of already built nodes: 00179 // Return 0 if OK and -1 otherwise. 00180 virtual int copyInNodes(const GP_Node &src, 00181 const GP_NodeTree &destpool); 00182 00183 00184 private: 00185 GEO_TPSurf *mySurf; 00186 UT_RefMatrix<GEO_PasteVertex> myCVs; 00187 GP_PointMatrix myGrev; 00188 float myHeight; 00189 int myPasteUp; 00190 int myNum; // used ONLY to resolve loading 00191 00192 // Special c-tor using for spawning. 00193 GEO_PasteSurf(GEO_TPSurf &tpsurf, GEO_PasteSurf &parent, int spawnkey); 00194 00195 // Assign us the the surface and vice versa, and update the GP_Domain's 00196 // internals. Used during load. 00197 void surface(GEO_TPSurf &tpsurf, int buildvertices = 1); 00198 00199 // Compute the Greville matrix from the original basis information: 00200 void buildGrevilles(void); 00201 00202 // Set up the diffuse CV matrix by mapping the Greville space into 3D 00203 // and computing CV displacements. Build the Grevilles first. 00204 void buildVertices(int originalgrev = 1); 00205 00206 // Change the local frame to point to the world greville image with an 00207 // identity matrix. This is almost equivalent to pasting onto a plane. 00208 // This method does not update the GEO_Points, so call updateWorldImage() 00209 // if you need to. 00210 void resetVertices(void); 00211 00212 // Anything goes in terms of spline surface changes, especially if it 00213 // involves changes of both knots and CVs, as in refinement, unrefinement, 00214 // degree elevation, or cutting. If "standalone" is 1, we temporarily go 00215 // back to our unpasted shape before calling (*apply)(). Return 0 if OK, 00216 // else -1. This method resets the base surfaces to self, and does not 00217 // update the GEO_Points if standalone is 1, so call updateWorldImage() 00218 // if you need to. 00219 virtual int modifyBasis(int (*apply)(void *tpsurf, void *d), 00220 void *data = 0, int standalone = 1); 00221 00222 // Assign myself to all the base surfaces: 00223 void initializeBases(void); 00224 00225 // Flip the pasting direction: 00226 void flipPaste(int up, int updateimage = 1); 00227 00228 // Update the texture coordinates of the surface by mapping the existing 00229 // ones to the transformed domain (using the frame xform). txtoff must be 00230 // >= 0 for anything to happen. 00231 void updateTextureCoordinates(int txtoff, int ptattrib = 1); 00232 00233 // Assuming that everything is clean, load the world values of the 00234 // transformed CVs into the GEO_Points. 00235 void updateWorldImage(void); 00236 00237 // A truly internal method, originalImage() loads the CVs from the original 00238 // grevilles and displacements and ignores the current frames and world 00239 // xform. Nothing else gets changed, so this is meant to be temporary. 00240 // We use this to apply spline algorithms on the original surface (eg. 00241 // refine it), and then go back to the pasted image. 00242 void buildOriginalImage(void); 00243 }; 00244 00245 #endif
1.5.9