00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _GQ_Detail_h_
00019 #define _GQ_Detail_h_
00020
00021 #include "GQ_API.h"
00022 #include <UT/UT_PtrArray.h>
00023 #include <UT/UT_IntArray.h>
00024 #include <UT/UT_Plane.h>
00025 #include <UT/UT_FloatArray.h>
00026 #include <UT/UT_RefArray.h>
00027
00028 #include <GEO/GEO_Primitive.h>
00029 #include <GU/GU_RayIntersect.h>
00030 #include <GU/GU_PrimPoly.h>
00031 #include <GU/GU_Types.h>
00032 #include "GQ_Error.h"
00033
00034 class GU_Detail;
00035 class GQ_Edge;
00036 class GQ_Face;
00037 class GQ_Point;
00038 class GEO_Point;
00039 class GEO_PrimPoly;
00040 class GB_PrimitiveGroup;
00041 class GB_Edge;
00042 class GB_EdgeGroup;
00043 class GQ_StitchParms;
00044 class GQ_SubdivideParms;
00045
00046 enum GQ_BooleanOpType {
00047 GQ_BOOLEAN_INTERSECT = 0,
00048 GQ_BOOLEAN_UNION = 1,
00049 GQ_BOOLEAN_A_MINUS_B = 2,
00050 GQ_BOOLEAN_B_MINUS_A = 3,
00051 GQ_BOOLEAN_A_EDGE = 4,
00052 GQ_BOOLEAN_B_EDGE = 5
00053 };
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 class GQ_API GQ_Detail {
00065 public:
00066
00067
00068
00069 GQ_Detail(GU_Detail *gdp,
00070 GB_PrimitiveGroup * = 0,
00071 float super_point_tolerance = 1E-6);
00072 ~GQ_Detail();
00073
00074 void clearAndDestroy(void);
00075
00076 void cusp(float angle, bool no_cut = false);
00077
00078
00079 void cusp(const GB_EdgeGroup &edges,
00080 bool do_cut = false);
00081
00082
00083
00084
00085
00086 void clip(UT_Vector3 &norm, float distance,
00087 int normalize);
00088 int crease(UT_Vector3 &norm, float distance,
00089 int normalize, int outputGroups,
00090 GB_PrimitiveGroup *primitive_above=0,
00091 GB_PrimitiveGroup *primitive_below=0);
00092
00093
00094 void bricker(float sizex = 1.0, float sizey = 1.0,
00095 float sizez = 1.0, float offx = 0.0,
00096 float offy = 0.0, float offz = 0.0,
00097 float anglex = 0.0, float angley = 0.0,
00098 float anglez = 0.0,
00099 bool fixsharededges = false);
00100 void doBoolean(const GU_Detail *A,
00101 const GU_Detail *B,
00102 GQ_BooleanOpType op,
00103 const int outputGroups = 0,
00104 const char *AgroupName = 0,
00105 const char *BgroupName = 0,
00106 int accurateAttrib = 0,
00107 int trials = 5);
00108 void smooth(int divisions, float relativeSize,
00109 float weight);
00110
00111
00112
00113
00114
00115
00116 void smoothPolygons(int iterations,
00117 GU_WeightingType type,
00118 float lambda, float mu,
00119 bool useptattrib,
00120 const GB_AttributeRef &attriboffset,
00121 int attribsize);
00122
00123
00124 void createEdgeWeights();
00125
00126
00127
00128
00129 void setCreaseWeight(const GEO_PrimPoly &poly,
00130 float weight);
00131
00132
00133
00134
00135 void setCreaseWeight(const GEO_PrimPoly &poly,
00136 const GB_AttributeRef &vtxoff,
00137 const GB_AttributeRef &primoff);
00138
00139
00140
00141 void setCreaseWeight(const GB_Edge &edge,
00142 float weight);
00143
00144
00145
00146
00147 void setCreaseWeight(const GB_Edge &gedge,
00148 const GB_AttributeRef &vtxoff,
00149 const GB_AttributeRef &primoff);
00150
00151
00152 float getEdgeWeight(const GB_Edge &edge);
00153 void subdivide(const GQ_SubdivideParms &parms,
00154 GB_PrimitiveGroup *nonsubdivprims);
00155 void dual();
00156 void stitch(const GQ_StitchParms &parms);
00157 int stitchEdges(GU_PrimPoly &polya,
00158 const UT_PtrArray<GU_PrimPoly *> &facea,
00159 GU_PrimPoly &polyb,
00160 const UT_PtrArray<GU_PrimPoly *> &faceb,
00161 GB_PrimitiveGroup &changedpolys,
00162 float tol, int clamp, int consolidate);
00163 void makeWire(float radius, int doSpheres,
00164 int doCaps);
00165 void buildGeometry();
00166 void buildCreases(GB_PrimitiveGroup *group = 0);
00167 void copyEdgeWeightToVertex();
00168 void unHole(int maintain);
00169 void boundary();
00170 void createCuspGroup(float, GB_PrimitiveGroup*grp);
00171 void createBoundaryGroup(GB_PrimitiveGroup &grp);
00172 void createBoundaryGroup(GB_PointGroup &grp,
00173 UT_IntArray *arr);
00174 void createBoundaryGroup(const GEO_Point *ppt,
00175 GB_PointGroup &pointgroup);
00176 void createBoundaryGroup(const GB_Edge &edge,
00177 GB_PointGroup &grp,
00178 GEO_PrimPoly *&poly);
00179
00180
00181
00182
00183
00184
00185 void createBoundaryList(UT_RefArray<UT_IntArray> &ptlist);
00186
00187
00188
00189
00190 void groupEdgePoints(const GEO_Point *ppt,
00191 int depth,
00192 GB_PointGroup &point_group);
00193
00194 int isClose();
00195
00196
00197
00198
00199 void deleteAllShareEdges();
00200
00201
00202 GQ_Point *appendPoint(const GQ_Point *src=0);
00203 GQ_Edge *appendEdge();
00204 GQ_Face *appendFace(GEO_PrimPoly *poly);
00205 void removePoint(GQ_Point *p);
00206 void removePoint(int i);
00207 void removeEdge(GQ_Edge *e);
00208 void removeEdge(int i);
00209 void removeFace(GQ_Face *f);
00210 void removeFace(int i);
00211 void collapseEdgeList() { myEdges.collapse(); }
00212 void collapseFaceList() { myFaces.collapse(); }
00213 UT_PtrArray<GQ_Point *> &getPointList() { return myPoints; }
00214 const UT_PtrArray<GQ_Point *>&getPointList() const { return myPoints; }
00215 UT_PtrArray<GQ_Edge *> &getEdgeList() { return myEdges; }
00216 const UT_PtrArray<GQ_Edge *>&getEdgeList() const{ return myEdges; }
00217 UT_FloatArray &getEdgeWeights() { return myEdgeWeights; }
00218 const UT_FloatArray &getEdgeWeights() const { return myEdgeWeights; }
00219 UT_PtrArray<GQ_Face *> &getFaceList() { return myFaces; }
00220 const UT_PtrArray<GQ_Face *>&getFaceList() const{ return myFaces; }
00221 GU_Detail *getGdp() { return myGdp; }
00222 const GU_Detail *getGdp() const { return myGdp; }
00223 GU_RayIntersect *getRay() { return myRay; }
00224 void buildRay()
00225 {
00226 if (myRay) delete myRay;
00227 myRay = new GU_RayIntersect(myGdp, myGroup);
00228 }
00229 UT_RefArray<GB_AttributeRef> &getOffsets() { return myOffsets; }
00230
00231
00232
00233 GQ_Point *splitEdge(GQ_Edge *edge, float t);
00234 void splitEdge(GQ_Edge *edge, GQ_Detail *B);
00235 GQ_Edge *splitEdge(GQ_Edge *, GQ_Point &pt);
00236 void deleteShareEdge(GQ_Edge *edge,
00237 GB_PrimitiveGroup *deletePrimGroup=0);
00238
00239 void wireEdge(GQ_Edge *edge, float radius,
00240 int doCaps);
00241 void pointSphere(GQ_Point *pt, float radius);
00242
00243 int nEdges(void) const { return myEdges.entries();}
00244 int nFaces(void) const { return myFaces.entries();}
00245 int nPoints(void) const{return myPoints.entries();}
00246 GU_Detail *getDetail(void) const { return myGdp; }
00247
00248 int aboveOrBelow(GQ_Face *face);
00249 void markPoints(GQ_Detail *B);
00250 void markEdges(GQ_Detail *B);
00251 void markFaces(GQ_Detail *B);
00252 void markFace(GQ_Face *f, GQ_Detail *B);
00253 void markComponent(GQ_Face *f, unsigned mark);
00254 void markComponent();
00255 void buildAllSplitFaces(GQ_Detail *B);
00256 void buildSplitFaces(GQ_Face *face,
00257 GQ_Edge *edge, GQ_Detail *B);
00258 void traceIntersectEdges();
00259 void traceIntersectEdges(GQ_Edge *edge);
00260 void cleanOffsets();
00261 void setupOffsets();
00262 void deleteAllFaces(GB_PrimitiveGroup *);
00263 void deleteAllMaskFaces(unsigned mask,
00264 GB_PrimitiveGroup *);
00265 void correctAllFaceMarkings();
00266 void flipAllFaceNormals();
00267
00268
00269 void simpleDecimate(int targetPolys);
00270 void meshOptimize(float tol = 1E-5);
00271 void decCollapse(GQ_Edge *e, GB_PrimitiveGroup *);
00272 void decSplit(GQ_Edge *e);
00273 void decSwap(GQ_Edge *e);
00274
00275
00276 void save(ostream &os) const;
00277 friend ostream &operator<<(ostream &os, const GQ_Detail &d)
00278 { d.save(os); return os; }
00279
00280
00281
00282 GQ_Edge *findEdge(const GB_Edge *edge);
00283 GQ_Edge *findEdge(const GQ_Point *org, const GQ_Point *dest);
00284 GEO_Point *stepForward(const GB_Edge *edge);
00285
00286
00287
00288 GEO_Point *pickArbitraryConnectedPoint(const GEO_Point *org);
00289
00290
00291
00292 GEO_Point *rotateAboutOrigin(GB_Edge &edge, int dir);
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 GQ_Detail *duplicate() const
00314 { return new GQ_Detail(*this); }
00315
00316
00317 GEO_PrimPoly *adjacentFace(const GEO_Face &face, int edge);
00318
00319 private:
00320
00321 GQ_Detail(const GQ_Detail &);
00322
00323
00324
00325
00326 GQ_Detail &operator=(const GQ_Detail &);
00327
00328
00329 void snapToPlane(UT_Vector3 &norm, float dist);
00330 void buildSuperPoints(float distance);
00331 GQ_Edge *findEdgeToShare(GQ_Point *org, GQ_Point *dest);
00332 GB_PrimitiveGroup *convertToQuadEdge(GB_PrimitiveGroup *,
00333 float sp_tol=0.001F);
00334 void addEdgeToPt(GQ_Edge *e, GQ_Point *p);
00335 void cleanEdgeToPt(GQ_Point *p);
00336 int buildFace(GQ_Face *face);
00337 int getVertexNum(const GQ_Face *face,
00338 const GEO_Point *prevPt,
00339 const GEO_Point *pt) const;
00340 void creaseFace(GQ_Face *face, UT_Vector3 &norm,
00341 float dist,
00342 int outputGroups,
00343 GB_PrimitiveGroup *prim_above = 0,
00344 GB_PrimitiveGroup *prim_below = 0);
00345 void createCreaseFace(GQ_Edge *edge,
00346 UT_Vector3 &norm, float dist,
00347 int outputGroups,
00348 GB_PrimitiveGroup *prim_above = 0,
00349 GB_PrimitiveGroup *prim_below = 0);
00350 void addIntersectEdges(GQ_Face *face,
00351 UT_Vector3 &normal);
00352
00353
00354
00355
00356 bool nonBridgeLoopHasFlag(GQ_Edge *e, int flag);
00357
00358
00359
00360
00361
00362
00363 void removeAllPossibleBridges(GQ_Face *face,
00364 UT_PtrArray<GQ_Edge *> &bridges);
00365 GQ_Edge * removePossibleBridge(GQ_Edge *bridgeEdge,
00366 bool hasisect,
00367 int depth,
00368 UT_PtrArray<GQ_Edge *> &bridges);
00369 void reBridge(UT_PtrArray<GQ_Edge *> &bridges);
00370 void reBridgeForCrease(UT_PtrArray<GQ_Edge *>
00371 &intersectBridges);
00372 UT_PtrArray<GQ_Face *> *split(UT_Vector3 &normal, float distance,
00373 int outputGroups = 0,
00374 GB_PrimitiveGroup *prim_above = 0,
00375 GB_PrimitiveGroup *prim_below = 0);
00376 void expandPoint(GQ_Point *pt);
00377 void plugGap(GQ_Edge *edge);
00378 void shrinkFace(GQ_Face *face, float a, float b);
00379 void unHole(GQ_Face *face, int maintain);
00380 GQ_Edge * unBridge(GQ_Edge *bridgeEdge, int maintain);
00381 void changeGeoPoint(GQ_Face *face, GEO_Point *opt,
00382 GEO_Point *npt, int all);
00383 void uniqueEdge(GQ_Edge *edge);
00384 void uniquePoint(GQ_Point *point);
00385 void cleanFace(GQ_Face *face);
00386 int twoFacesShareAllEdges(GQ_Edge *edge,
00387 GB_PrimitiveGroup *deletePrimGroup);
00388
00389
00390 void calcFacePoints(int numfaces);
00391 void calcEdgePoints(int numedges,
00392 GEO_Vertex **oldEdgeAttribs,
00393 bool smoothvertex);
00394 void calcVertexPoints(int numpoints,
00395 GEO_Vertex **oldEdgeAttribs,
00396 GB_AttributeData *newVertexAttribs,
00397 bool smoothvertex);
00398
00399
00400
00401 void copyVertexAttributeByPoint(int numpoints,
00402 GB_AttributeData *newVertexAttribs);
00403 void calcEdgeAttribs(int numedge);
00404
00405
00406 void flagVertexBoundaries();
00407 void subdivideEdges(int numedges, bool linear);
00408 void subdivideFaces(int numfaces);
00409
00410
00411 void copyVertexAttributes(int numedges);
00412
00413 void splitPolysWithMultipleHoles(GB_PrimitiveGroup *,
00414 UT_PtrArray<GQ_Point *> &);
00415 GEO_PrimPoly *findNonSubDivPolyWithEdge(const GEO_Point *,
00416 const GEO_Point *, GB_PrimitiveGroup *, int &,
00417 int &);
00418 GEO_PrimPoly *findNonSubDivPolyWithEdge(const GEO_Point *,
00419 const GEO_Point *, GB_PrimitiveGroup *);
00420 GQ_Edge *findBoundEdge(const GQ_Point *, const GQ_Point *,
00421 UT_Vector4 &, UT_Vector4 &, int &);
00422 int addSubDivBoundaryPoints(GQ_Edge *, const GQ_Point *,
00423 GB_PointGroup *);
00424 void createVirtualEdgePoints(const UT_Vector4 &,
00425 const UT_Vector4 &, GB_PointGroup *,
00426 UT_Vector4Array &);
00427 void createActualEdgePoints(const UT_Vector4 &,
00428 const UT_Vector4 &, GB_PointGroup *,
00429 GB_PointGroup *);
00430 void triangulateNonSubDivPoly(GEO_PrimPoly *,
00431 GB_PointGroup *, GB_PrimitiveGroup *,
00432 GEO_Point *, GEO_Point *, GEO_Point *, GEO_Point *,
00433 int);
00434 GEO_PrimPoly *dividePolygonContainingEdge(GB_PointGroup *,
00435 const GEO_Point *, const GEO_Point *,
00436 GB_PrimitiveGroup *, int,
00437 GEO_Point *&, GEO_Point *&);
00438 void pullHolesUsingBias(GB_PointGroup *,
00439 UT_Vector4Array &, float);
00440 void stitchHoles(GB_PointGroup *, GB_PointGroup *,
00441 GEO_PrimPoly *, int);
00442 void pullToEndPoints(GB_PointGroup *, GEO_Point *,
00443 GEO_Point *);
00444 void closeHolesAfterSubdivide(UT_PtrArray<GQ_Point *> &,
00445 GB_PrimitiveGroup *, const GQ_SubdivideParms &);
00446
00447
00448
00449 void cuspPoint(GQ_Point *p, GB_AttributeRef normalOffset, int i);
00450
00451
00452 UT_PtrArray<GQ_Edge *> myEdges;
00453 UT_FloatArray myEdgeWeights;
00454 UT_PtrArray<GQ_Point *> myEdgePoints;
00455 UT_PtrArray<GQ_Face *> myFaces;
00456 UT_PtrArray<GQ_Point *> myPoints;
00457 UT_RefArray<GB_AttributeRef> myOffsets;
00458 GB_PrimitiveGroup *myGroup;
00459 GU_Detail *myGdp;
00460 GU_RayIntersect *myRay;
00461
00462
00463
00464
00465
00466 UT_PtrArray<GEO_Vertex *> myEdgeAttribs;
00467 UT_PtrArray<GEO_Vertex *> myFaceAttribs;
00468 };
00469
00470 #endif