spline3d.h

Go to the documentation of this file.
00001 //
00002 // Copyright 2010 Autodesk, Inc.  All rights reserved.
00003 //
00004 // Use of this software is subject to the terms of the Autodesk license
00005 // agreement provided at the time of installation or download, or which
00006 // otherwise accompanies this software in either electronic or hard copy form.  
00007 //
00008 //
00009 
00010 #pragma once
00011 
00012 #include "maxheap.h"
00013 #include "polyshp.h"    // Need this for PolyLine class
00014 #include "GraphicsConstants.h"
00015 
00016 // forward declarations
00017 class ViewExp;
00018 class IObjParam;
00019 
00021 
00022 #define BEZ_SHAPE_KNOT          (1<<0)  //!< A knot point
00023 #define BEZ_SHAPE_INTERPOLATED  (1<<1)  //!< An interpolated point between two knots
00024 
00025 
00026 
00028 
00029 #define LTYPE_CURVE 0   //!< Specifies that the segment should interpolate based on the bezier handles for the segment.
00030 #define LTYPE_LINE 1    //!< Specifies that the segment should go straight from knot to knot and ignore the bezier handles.
00031 
00032 
00034 
00035 #define CURVE_CURVE (LTYPE_CURVE | (LTYPE_CURVE<<2))
00036 #define LINE_CURVE (LTYPE_LINE | (LTYPE_CURVE<<2))
00037 #define CURVE_LINE (LTYPE_CURVE | (LTYPE_LINE<<2))
00038 #define LINE_LINE (LTYPE_LINE | (LTYPE_LINE<<2))
00039 
00040 
00042 
00043 
00045 #define KTYPE_AUTO 0    
00046 
00047 #define KTYPE_CORNER 1
00048 
00054 #define KTYPE_BEZIER 2
00055 
00056 #define KTYPE_BEZIER_CORNER (KTYPE_BEZIER | KTYPE_CORNER)
00057 #define KTYPE_RESET 4
00058 
00059 
00063 #define PARM_UNIFORM        0
00064 #define PARM_ARCLENGTH      1
00065 #define PARM_CENTRIPETAL    2
00066 #define PARM_CUSTOM         3
00067 
00068 
00070 
00071 #define DRAW_IDLE 0
00072 #define DRAW_INITIAL_MOUSE_DOWN 1
00073 #define DRAW_FREEMOVE_POINT 2
00074 #define DRAW_FREEMOVE_POINT_MOUSE_DOWN 3    //!< Inserting's initial click inside spline
00075 #define DRAW_INITIAL_BEZ_ADJ 11
00076 #define DRAW_DRAGGING_VECTOR 22
00077 
00078 
00080 
00081 #define SPLINE_INTERP_SIMPLE 0      //!< Parameter space based on segments
00082 #define SPLINE_INTERP_NORMALIZED 1  //!< Parameter space normalized to curve length
00083 
00084 
00085 class Spline3D;
00086 class SplineKnotAssy;
00087 class SplineKnot;             
00088 
00094 class SplinePoint: public MaxHeapOperators {
00095     friend class Spline3D;
00096     friend class SplineKnotAssy;
00097     friend class SplineKnot;
00098 
00099     private:
00100         Point3 point;
00101         int aux[3];
00102     public:
00103         CoreExport SplinePoint();
00104         CoreExport SplinePoint(Point3 &p, int a1 = -1, int a2 = -1, int a3 = -1);
00105         CoreExport SplinePoint& operator=(SplinePoint &fromSP);
00106         inline Point3& GetPoint() { return point; }
00107         inline int GetAux(int index) { return aux[index]; }
00108         inline void SetPoint(const Point3 &p) { point = p; }
00109         inline void SetAux(int index, int a) { aux[index] = a; }
00110     };
00111 
00112 
00113 #define SPLINE_MATID_SHIFT  16      //!< The mat ID is stored in the HIWORD of the knot flags
00114 #define SPLINE_MATID_MASK   0xFFFF  //!< The mat ID is stored in the HIWORD of the knot flags
00115 //watje
00116 #define SEGMENT_VISIBLE     (1<<0)
00117 #define SPLINEKNOT_NO_SNAP  (1<<1)  //!< Suppresses snapping to knot if set
00118 
00125 #define SPLINEKNOT_ADD_SEL  (1<<2)  //!< Additional selection for transformation
00126 
00129 class SplineKnotAssy: public MaxHeapOperators {
00130     friend class Spline3D;
00131     friend class SplineKnot;
00132 
00133     private:
00134         int ktype;          // Knot type
00135         int ltype;          // Line type
00136         float du;           // Parameter value
00137         SplinePoint inVec;  // The in vector
00138         SplinePoint knot;   // The knot
00139         SplinePoint outVec; // The out vector
00140         DWORD flags;
00141     public:
00142         CoreExport SplineKnotAssy();
00143         CoreExport SplineKnotAssy(int k, int l, Point3 p, Point3 in, Point3 out, int a1= -1, int a2= -1, int a3= -1, int Ia1= -1, int Ia2= -1, int Ia3= -1, int Oa1= -1, int Oa2= -1, int Oa3= -1, DWORD f=0);
00144         CoreExport SplineKnotAssy(int k, int l, SplinePoint p, SplinePoint in, SplinePoint out, DWORD f=0);
00145         CoreExport SplineKnotAssy(SplineKnot &k);
00146         inline  int     Ktype() { return ktype; }
00147         inline  void    SetKtype(int t) { ktype=t; }
00148         inline  int     Ltype() { return ltype; }
00149         inline  void    SetLtype(int t) { ltype=t; }
00150         inline  Point3  Knot() { return knot.point; }
00151         inline  void    SetKnot(const Point3 &p) { knot.point=p; }
00152         inline  Point3  InVec() { return inVec.point; }
00153         inline  void    SetInVec(const Point3 &p) { inVec.point=p; }
00154         inline  Point3  OutVec() { return outVec.point; }
00155         inline  void    SetOutVec(const Point3 &p) { outVec.point=p; }
00156         inline  float   GetParm() { return du; }
00157         inline  void    SetParm(float p) { du = p; }
00158         inline  MtlID   GetMatID() {return (int)((flags>>SPLINE_MATID_SHIFT)&SPLINE_MATID_MASK);}
00159         inline  void    SetMatID(MtlID id) {flags &= 0xFFFF; flags |= (DWORD)(id<<SPLINE_MATID_SHIFT);}
00160         
00164         CoreExport int  GetAux(int index, int which);
00165 
00169         CoreExport void SetAux(int index, int which, int value);
00170 
00174         CoreExport Point3 GetVert(int index);
00175 
00179         CoreExport void SetVert(int index, const Point3 &p);
00180 
00181         inline  SplinePoint GetKnot() { return knot; }
00182         inline  SplinePoint GetInVec() { return inVec; }
00183         inline  SplinePoint GetOutVec() { return outVec; }
00184         inline  void SetKnot(SplinePoint &sp) { knot = sp; }
00185         inline  void SetInVec(SplinePoint &sp) { inVec = sp; }
00186         inline  void SetOutVec(SplinePoint &sp) { outVec = sp; }
00187         inline  DWORD GetFlags() { return flags; }
00188 
00189 //watje     
00190         inline  BOOL    IsHidden() {return (flags&SEGMENT_VISIBLE);}
00191         inline  void    Hide() { flags |= (DWORD)(SEGMENT_VISIBLE);}
00192         inline  void    Unhide() { flags &= (DWORD)(~SEGMENT_VISIBLE);}
00193 //TH 8/22/00
00194         inline  BOOL    IsNoSnap() {return (flags&SPLINEKNOT_NO_SNAP);}
00195         inline  void    SetNoSnap() { flags |= (DWORD)(SPLINEKNOT_NO_SNAP);}
00196         inline  void    ClearNoSnap() { flags &= (DWORD)(~SPLINEKNOT_NO_SNAP);}
00197 // CAL-05/23/03
00198         inline  BOOL    GetFlag (DWORD fl) { return (flags & fl) ? TRUE : FALSE; }
00199         inline  void    SetFlag (DWORD fl, BOOL val=TRUE) { if (val) flags |= fl; else flags &= ~fl; }
00200         inline  void    ClearFlag (DWORD fl) { flags &= ~fl; }
00201     };
00202 
00230 class SplineKnot: public MaxHeapOperators {
00231     friend class Spline3D;
00232     friend class SplineKnotAssy;
00233 
00234     int ktype;
00235     int ltype;
00236     Point3 point;
00237     Point3 inVec;
00238     Point3 outVec;
00239     int aux;        // Used for capping
00240     int aux2;       // Used to track topo changes in spline editing
00241     int aux3;       // User aux field
00242     int inAux;
00243     int inAux2;
00244     int inAux3;
00245     int outAux;
00246     int outAux2;
00247     int outAux3;
00248     DWORD flags;
00249 public:
00250     CoreExport SplineKnot();
00251     
00265     CoreExport SplineKnot(int k, int l, Point3 p, Point3 in, Point3 out, int a1= -1, int a2= -1, int a3= -1, int Ia1= -1, int Ia2= -1, int Ia3= -1, int Oa1= -1, int Oa2= -1, int Oa3= -1, DWORD f=0);
00266     CoreExport SplineKnot(SplineKnotAssy &k);
00267 
00270     inline  int     Ktype() { return ktype; }
00271 
00275     inline  void    SetKtype(int t) { ktype=t; }
00276 
00279     inline  int     Ltype() { return ltype; }
00280 
00284     inline  void    SetLtype(int t) { ltype=t; }
00285 
00288     inline  int     Aux() { return aux; }
00289 
00292     inline  void    SetAux(int a) { aux=a; }
00293 
00295     inline  int     Aux2() { return aux2; }
00296 
00299     inline  void    SetAux2(int a) { aux2=a; }
00300 
00301     inline  int     Aux3() { return aux3; }
00302     inline  void    SetAux3(int a) { aux3=a; }
00303     inline  int     InAux() { return inAux; }
00304     inline  void    SetInAux(int a) { inAux=a; }
00305     inline  int     InAux2() { return inAux2; }
00306     inline  void    SetInAux2(int a) { inAux2=a; }
00307     inline  int     InAux3() { return inAux3; }
00308     inline  void    SetInAux3(int a) { inAux3=a; }
00309     inline  int     OutAux() { return outAux; }
00310     inline  void    SetOutAux(int a) { outAux=a; }
00311     inline  int     OutAux2() { return outAux2; }
00312     inline  void    SetOutAux2(int a) { outAux2=a; }
00313     inline  int     OutAux3() { return outAux3; }
00314     inline  void    SetOutAux3(int a) { outAux3=a; }
00315 
00317     inline  Point3  Knot() { return point; }
00318 
00321     inline  void    SetKnot(Point3 p) { point=p; }
00322 
00324     inline  Point3  InVec() { return inVec; }
00325 
00328     inline  void    SetInVec(Point3 p) { inVec=p; }
00329 
00331     inline  Point3  OutVec() { return outVec; }
00332 
00335     inline  void    SetOutVec(Point3 p) { outVec=p; }
00336 
00337     inline  MtlID   GetMatID() {return (int)((flags>>SPLINE_MATID_SHIFT)&SPLINE_MATID_MASK);}
00338     inline  void    SetMatID(MtlID id) {flags &= 0xFFFF; flags |= (DWORD)(id<<SPLINE_MATID_SHIFT);}
00339     inline  DWORD   GetFlags() { return flags; }
00340 
00341 //watje
00342     inline  BOOL    IsHidden() {return (flags&SEGMENT_VISIBLE);}
00343     inline  void    Hide() { flags |= (DWORD)(SEGMENT_VISIBLE);}
00344     inline  void    Unhide() { flags &= (DWORD)(~SEGMENT_VISIBLE);}
00345 //TH 8/22/00
00346     inline  BOOL    IsNoSnap() {return (flags&SPLINEKNOT_NO_SNAP);}
00347     inline  void    SetNoSnap() { flags |= (DWORD)(SPLINEKNOT_NO_SNAP);}
00348     inline  void    ClearNoSnap() { flags &= (DWORD)(~SPLINEKNOT_NO_SNAP);}
00349 // CAL-05/23/03
00350     inline  BOOL    GetFlag (DWORD fl) { return (flags & fl) ? TRUE : FALSE; }
00351     inline  void    SetFlag (DWORD fl, BOOL val=TRUE) { if (val) flags |= fl; else flags &= ~fl; }
00352     inline  void    ClearFlag (DWORD fl) { flags &= ~fl; }
00353     };
00354 
00356 
00357 #define SPLINE_CLOSED   (1<<0)
00358 #define SPLINE_ORTHOG   (1<<1)
00359 
00360 
00366 class Spline3D: public MaxHeapOperators {
00367     friend class BezierShape;
00368     friend class SplineShape;
00369     friend class Railing; 
00370 private:
00371     static  int         splineCount;    // Number of splines in the system
00372             int         parmType;       // Interpolation parameter type (needed?)
00373             int         knotCount;      // Number of points in spline
00374 
00375             int         flags;          // Private flags
00376             int         iCur;           // Current editing point
00377             int         Interact(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3* mat, IObjParam* ip=NULL ); // Handle mouse interaction
00378             float       cachedLength;
00379             BOOL        cacheValid;
00380             SplineKnotAssy* knots;      // Knot assembly array
00381             float *     lengths;        // Cached lengths
00382             float *     percents;       // Cached length percentages
00383             int         drawPhase;      // Drawing phase
00384             int         editMode;       // 1 if editing, 0 otherwise
00385 
00386             // Creation settings
00387             int         initialType;    // Knot type at initial click
00388             int         dragType;       // Knot type at drag
00389             
00390             BOOL        selfInt;        // Cached self-intersection flag
00391             BOOL        siCacheValid;   // Self-intersection cache valid?
00392             Box3        bbox;           // Cached bounding box
00393             BOOL        bboxValid;      // Bounding box valid?
00394             BOOL        paramsValid;    // Knot parameter values valid?
00395             BOOL        bezPointsValid; // Bezier points valid?
00396             BOOL        clockwise;      // Clockwise cache
00397             BOOL        cwCacheValid;   // Clockwise cache valid?
00398             PolyLine    polyLine;       // Polyline cache
00399             BOOL        plineOpt;
00400             int         plineSteps;
00401             BOOL        plineCacheValid;    // Polyline cache valid?
00402 protected:
00403     CoreExport      void        Allocate(int count);
00404     CoreExport      void        ChordParams();                          // Compute chord length params
00405     CoreExport      void        UniformParams();                        // Compute uniform params
00406     CoreExport      void        CentripetalParams();                    // Compute centripetal params
00407     CoreExport      void        LinearFwd(int i);
00408     CoreExport      void        LinearBack(int i);
00409     CoreExport      void        ContinFwd(int i);
00410     CoreExport      void        ContinBack(int i);
00411     CoreExport      void        HybridPoint(int i);
00412     CoreExport      void        CompCornerBezPoints(int n);
00413     CoreExport      void        CompAdjBesselBezPoints(int i);
00414     CoreExport      void        BesselStart(int i);
00415     CoreExport      void        BesselEnd(int i);
00416     CoreExport      void        NaturalFwd(int i);
00417     CoreExport      void        NaturalBack(int i);
00418 public:
00419 
00425     CoreExport      Spline3D(int itype = KTYPE_CORNER,int dtype = KTYPE_BEZIER,int ptype = PARM_UNIFORM);
00426     CoreExport      Spline3D(Spline3D& fromSpline);
00427 
00429     CoreExport      virtual ~Spline3D();
00430 
00432     CoreExport      Spline3D&   operator=(Spline3D& fromSpline);
00433 
00438     CoreExport      Spline3D&   operator=(PolyLine& fromLine);
00439 
00442     CoreExport      void        NewSpline();
00443 
00445     inline          int         ParmType() { return parmType; };
00446 
00448     inline          int         KnotCount() { return knotCount; }                   
00449     
00453     inline          int         Flags() { return flags; }
00454 
00457     CoreExport      int         Segments();
00458 
00460     inline          int         Closed() { return (flags & SPLINE_CLOSED) ? 1:0; }
00461 
00463     CoreExport      int         ShiftKnot(int where,int direction);                     // Shove array left or right 1,
00464     
00470     CoreExport      int         AddKnot(SplineKnot &k,int where = -1);                  // Add a knot to the spline
00471     
00476     CoreExport      void        SetKnot(int i, SplineKnot &k);
00477     
00481     CoreExport      SplineKnot  GetKnot(int i);
00482 
00486     CoreExport      int         DeleteKnot(int where);                                  // Delete the specified knot
00487     
00498     CoreExport      int         Create(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3* mat, IObjParam *ip=NULL);    // Create the spline
00499     
00504     CoreExport      int         StartInsert(ViewExp *vpt,int msg, int point, int flags, IPoint2 theP, Matrix3* mat, int where );    // Start an insertion operation on the spline
00505     
00507     CoreExport      int         SetParam(int index,float param);        // Set custom param value
00508     
00510     CoreExport      float       GetParam(int index);                    // Get param value
00511     
00515     inline          int         GetKnotType(int index) { return knots[index].ktype; }
00516     
00523     CoreExport      int         SetKnotType(int index,int type);        // Set the knot type
00529     inline          int         GetLineType(int index) { return knots[index].ltype; }
00530     
00536     CoreExport      int         SetLineType(int index,int type);        // Set the line type
00537     
00539     virtual         void        CustomParams() { UniformParams(); }     // Replace this as needed
00540     
00542     CoreExport      void        CompParams();                           // Compute param values
00543     
00547     CoreExport      void        ComputeBezPoints();
00548     
00550     CoreExport      void        FindSegAndParam(float u, int ptype, int &seg, float &param);
00551     CoreExport      void        RefineCurve(float u, int ptype=SPLINE_INTERP_SIMPLE);
00552     CoreExport      void        RefineSegment(int segment, float t, int ptype=SPLINE_INTERP_SIMPLE);
00553     
00556     CoreExport      Point2      InterpBezier(IPoint2 *bez, float t);
00557     
00563     CoreExport      Point3      InterpBezier3D(int segment, float t, int ptype=SPLINE_INTERP_SIMPLE);
00564     
00571     CoreExport      Point3      InterpCurve3D(float u, int ptype=SPLINE_INTERP_SIMPLE);
00572     
00578     CoreExport      Point3      TangentBezier3D(int segment, float t, int ptype=SPLINE_INTERP_SIMPLE);
00579     
00584     CoreExport      Point3      TangentCurve3D(float u, int ptype=SPLINE_INTERP_SIMPLE);
00585     
00587     CoreExport      Point3      AverageTangent(int i);
00588     
00590     CoreExport      void        MakeBezCont(int i);
00591     
00593     CoreExport      void        RedistTangents(int i, Point3 d);
00594     
00596     CoreExport      void        FixAdjBezTangents(int i);
00597     
00599     CoreExport      void        DrawCurve(GraphicsWindow *gw, Material *mtl);
00600     
00602     inline          void        SetEditMode(int mode) { editMode = mode ? 1:0; }
00603     
00606     CoreExport      int         IsAuto(int i);
00607     
00610     CoreExport      int         IsBezierPt(int i);
00611     
00614     CoreExport      int         IsCorner(int i);
00615     
00617     CoreExport      Point3      GetDragVector(ViewExp *vpt,IPoint2 p,int i,Matrix3* mat);
00618     
00620     CoreExport      int         AppendPoint(ViewExp *vpt,const Point3& p, int where = -1);
00621     
00623     CoreExport      int         DrawPhase() { return drawPhase; }
00624     
00626     CoreExport      int         GetiCur() { return iCur; }
00627     
00633     CoreExport      void        GetBBox(TimeValue t,  Matrix3& tm, Box3& box);
00634     
00636     CoreExport      IPoint2     ProjectPoint(ViewExp *vpt, Point3 fp, Matrix3 *mat);
00637     
00639     CoreExport      Point3      UnProjectPoint(ViewExp *vpt, IPoint2 p, Matrix3 *mat);
00640     
00642     CoreExport      void        Snap(GraphicsWindow *gw, SnapInfo *snap, IPoint2 *p, Matrix3 &tm);
00643 
00646     CoreExport      IOResult    Save(ISave *isave);
00647     
00650     CoreExport      IOResult    Load(ILoad *iload);
00651     
00656     CoreExport      int         SetClosed(int flag = 1);
00657     
00660     CoreExport      int         SetOpen();
00661     
00666     CoreExport      void        Dump(int where);
00667     
00670     CoreExport      Point3      GetInVec(int i);
00671 
00675     CoreExport      void        SetInVec(int i, const Point3 &p);
00676     
00679     CoreExport      Point3      GetRelInVec(int i);
00680     
00684     CoreExport      void        SetRelInVec(int i, const Point3 &p);
00685     
00688     CoreExport      Point3      GetKnotPoint(int i);
00689     
00693     CoreExport      void        SetKnotPoint(int i, const Point3 &p);
00694     
00697     CoreExport      Point3      GetOutVec(int i);
00698     
00702     CoreExport      void        SetOutVec(int i, const Point3 &p);
00703     
00706     CoreExport      Point3      GetRelOutVec(int i);
00707     
00711     CoreExport      void        SetRelOutVec(int i, const Point3 &p);
00712     
00713     // The following methods return absolute coords for the bezier vertices
00714     
00720     CoreExport      Point3      GetVert(int i);
00721     
00723     CoreExport      void        SetVert(int i, const Point3& p);
00724     
00727     inline          int         Verts() { return knotCount*3; }
00728     
00729     // The following methods get/set the knot aux fields based on knot index
00730     // These are here for backward compatibility with MAXr2
00731     
00737     CoreExport      int         GetAux(int knot);
00738     
00742     CoreExport      void        SetAux(int knot, int value);
00743     
00746     CoreExport      int         GetAux2(int knot);
00747     
00751     CoreExport      void        SetAux2(int knot, int value);
00752     
00756     CoreExport      int         GetAux3(int knot);
00757     
00762     CoreExport      void        SetAux3(int knot, int value);
00763     
00764     // The following methods are new to MAXr3 and get/set aux fields for in/knot/out
00765     // knot: knot index
00766     // which: 0=aux1 1=aux2 2=aux3
00767     
00771     CoreExport      int         GetKnotAux(int knot, int which);
00772     
00777     CoreExport      void        SetKnotAux(int knot, int which, int value);
00778     
00782     CoreExport      int         GetInAux(int knot, int which);
00783     
00788     CoreExport      void        SetInAux(int knot, int which, int value);
00789     
00793     CoreExport      int         GetOutAux(int knot, int which);
00794     
00799     CoreExport      void        SetOutAux(int knot, int which, int value);
00800     
00801     // The following methods get/set the aux fields based on bezier vertex index
00802     // i: bezier vertex index
00803     // which: 0=aux1 1=aux2 2=aux3
00804     
00809     CoreExport      int         GetVertAux(int i, int which);
00810     
00816     CoreExport      void        SetVertAux(int i, int which, int value);
00817     
00818     // The following methods get/set the material ID for a spline segment
00819     
00822     CoreExport      MtlID       GetMatID(int seg);
00823     
00827     CoreExport      void        SetMatID(int seg, MtlID id);
00828 
00830     CoreExport      float       SplineLength();
00831 
00834     CoreExport      float       SegmentLength(int seg);
00835     
00839     CoreExport      void        Transform(Matrix3 *tm);
00840 
00846     CoreExport      void        Reverse(BOOL keepZero = FALSE);
00847     
00854     CoreExport      BOOL        Append(Spline3D *spline, BOOL weldCoincidentFirstVertex=TRUE);  
00855 
00859     CoreExport      BOOL        Prepend(Spline3D *spline, BOOL weldCoincidentLastVertex=TRUE);
00860     
00863     CoreExport      BOOL        IsClockWise();
00864     
00867     CoreExport      BOOL        SelfIntersects();
00868 
00874     CoreExport      BOOL        IntersectsSpline(Spline3D *spline);
00875     
00879     CoreExport      BOOL        SurroundsPoint(Point2 p);
00880 
00891     CoreExport      void        MakePolyLine(PolyLine &line, int steps = -1, BOOL optimize = FALSE);
00892 
00895     CoreExport      void        InvalidateGeomCache();
00896 
00906     CoreExport      void        GetSmoothingMap(IntTab &map);
00907     };
00908