MNNormalSpec.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  *<
00003     FILE: MNNormalSpec.h
00004 
00005     DESCRIPTION:  User-specifiable normals for MNMeshes - Luna task 747
00006 
00007     CREATED BY: Steve Anderson
00008 
00009     HISTORY: created January 2002
00010 
00011  *> Copyright (c) 2002 Autodesk, Inc., All Rights Reserved.
00012  **********************************************************************/
00013 #pragma once
00014 
00015 #include "export.h"
00016 #include "maxheap.h"
00017 #include "baseinterface.h"
00018 #include "ipipelineclient.h"
00019 #include "bitarray.h"
00020 #include "mncommon.h"
00021 #include "box3.h"
00022 
00023 // forward declarations
00024 class MNFace;
00025 class MNMesh;
00026 class Point3;
00027 class GraphicsWindow;
00028 class HitRegion;
00029 class SubObjHitList;
00030 
00031 #define MN_NORMAL_SPEC_INTERFACE Interface_ID(0x7b7c2c5f, 0xf94260f)
00032 
00039 class MNNormalFace: public MaxHeapOperators {
00040     int mDegree;
00041     int *mpNormalID;
00042     BitArray mSpecified;
00043 
00044 public:
00048     MNNormalFace () : mDegree(0), mpNormalID(NULL) { }
00051     DllExport MNNormalFace (int degree);
00054     ~MNNormalFace () { Clear(); }
00061     DllExport void Init();
00064     DllExport void Clear();
00065 
00066     // Data accessors
00069     int GetDegree() { return mDegree; }
00071     DllExport void SetDegree (int degree);
00072     // Low-level - do not use mSpecified data!
00083     int GetNormalID(int corner) { return (mpNormalID && (corner<mDegree)) ? mpNormalID[corner] : -1; }
00092     void SetNormalID (int corner, int norm) { if (mpNormalID && (corner<mDegree)) mpNormalID[corner] = norm; }
00093 
00095     int *GetNormalIDArray () { return mpNormalID; }
00096 
00105     bool GetSpecified (int corner) { return (mpNormalID && (corner<mDegree) && mSpecified[corner]) ? true : false; }
00119     void SetSpecified (int corner, bool value=true) { if (mpNormalID && (corner<mDegree)) mSpecified.Set (corner, value); }
00120 
00122     void SpecifyAll (bool value=true) { if (value) mSpecified.SetAll(); else mSpecified.ClearAll(); }
00135     DllExport void SpecifyNormalID (int corner, int norm);
00136 
00137     DllExport void MakePoly (int degree, int *pNormalID);
00149     DllExport void Insert (int pos, int num=1);
00161     DllExport void Delete (int pos, int num=1);
00169     DllExport void RotateStart (int newstart);
00173     DllExport void Flip (); // Reverses order of verts.  0 remains start.
00174 
00179     DllExport MNNormalFace & operator= (const MNNormalFace & from);
00183     DllExport MNNormalFace & operator= (const MNFace & from);
00190     DllExport void ShallowTransfer (MNNormalFace & from);
00201     DllExport void MNDebugPrint (bool printAll=false);
00202 
00206     DllExport IOResult Save (ISave *isave);
00209     DllExport IOResult Load (ILoad *iload);
00210 };
00211 
00212 // Class MNNormalSpec flags:
00213 #define MNNORMAL_NORMALS_BUILT 0x01
00214 #define MNNORMAL_NORMALS_COMPUTED 0x02
00215 #define MNNORMAL_DISPLAY_HANDLES 0x04
00216 #define MNNORMAL_FACE_ANGLES 0x08   // Used face angles last time we computed normals
00217 
00218 // Default length for normal display
00219 #define MNNORMAL_LENGTH_DEFAULT 10.0f
00220 
00277 class MNNormalSpec : public IPipelineClient, public FlagUser {
00278 private:
00279     int mNumNormalAlloc, mNumFaceAlloc;
00280     int mNumNormals, mNumFaces;
00281     MNNormalFace *mpFace;
00282     Point3 *mpNormal;
00283     BitArray mNormalExplicit;   // Indicates whether mpNormal[i] is explicit or computed from face normals.
00284 
00285     // Display and selection data:
00286     BitArray mNormalSel;
00287     float mDisplayLength;
00288 
00289     // We also maintain a pointer to the parent MNMesh
00290     // (NOTE that the MNMesh MUST keep this pointer updated at all times!)
00291     MNMesh *mpParent;
00292 
00293 public:
00296     MNNormalSpec () : mpFace(NULL), mpNormal(NULL), mNumNormalAlloc(0),
00297         mNumFaceAlloc(0), mNumNormals(0), mNumFaces(0), mpParent(NULL),
00298         mDisplayLength(MNNORMAL_LENGTH_DEFAULT) { }
00300     ~MNNormalSpec () { ClearAndFree (); }
00301 
00302     // Initialization, allocation:
00307     DllExport void Initialize ();   // Initializes all data members - do not use if already allocated!
00313     DllExport bool NAlloc (int num, bool keep=TRUE);
00317     DllExport void NShrink ();  // shrinks allocation down to actual number of normals.
00323     DllExport bool FAlloc (int num, bool keep=TRUE);
00327     DllExport void FShrink ();
00331     DllExport void Clear ();    // Deletes everything.
00334     DllExport void ClearAndFree (); // Deletes everything, frees all memory
00335 
00336     // Data access:
00337     // Lowest level:
00341     int GetNumFaces () const { return mNumFaces; }
00349     DllExport bool SetNumFaces (int numFaces);
00353     int GetNumNormals () const { return mNumNormals; }
00361     DllExport bool SetNumNormals (int numNormals);
00362 
00369     Point3 & Normal (int normID) const { return mpNormal[normID]; }
00372     Point3 * GetNormalArray () const { return mpNormal; }
00376     bool GetNormalExplicit (int normID) const { return mNormalExplicit[normID] ? true : false; }
00389     void SetNormalExplicit (int normID, bool value) { mNormalExplicit.Set (normID, value); }
00390 
00392     void SetAllExplicit (bool value=true) { if (value) mNormalExplicit.SetAll(); else mNormalExplicit.ClearAll (); }
00395     MNNormalFace & Face(int faceID) const { return mpFace[faceID]; }
00398     MNNormalFace * GetFaceArray () const { return mpFace; }
00399 
00415     void SetParent (MNMesh *pMesh) { mpParent = pMesh; }
00416 
00417     // Data access - higher level:
00421     DllExport Point3 & GetNormal (int face, int corner);
00427     DllExport void SetNormal (int face, int corner, Point3 & normal);
00432     DllExport int GetNormalIndex (int face, int corner);
00437     DllExport void SetNormalIndex (int face, int corner, int normalIndex);
00449     DllExport int NewNormal (Point3 & normal, bool explic=true);
00450 
00453     DllExport void SetSelection (BitArray & newSelection);
00456     BitArray & GetSelection() { return mNormalSel; }
00460     void SetDisplayLength (float displayLength) { mDisplayLength = displayLength; }
00464     float GetDisplayLength () { return mDisplayLength; }
00465 
00475     DllExport void CollapseDeadFaces ();    // Requires an accurate mpParent pointer.
00476 
00477     // Display and hit testing - note that these require an accurate mpParent pointer.
00484     DllExport void Display (GraphicsWindow *gw, bool showSel);
00503     DllExport bool HitTest (GraphicsWindow *gw, HitRegion *hr, DWORD flags, SubObjHitList& hitList);
00515     DllExport Box3 GetBoundingBox (Matrix3 *tm=NULL, bool selectedOnly=false);
00516 
00517     // This method dumps all unspecified normals.  Best to use only from within CheckNormals.
00522     DllExport void ClearNormals ();
00523 
00524     // Fills in the mpSpecNormal data by building all the unspecified normals,
00525     // and computing non-explicit ones.
00526     // Does nothing if normal faces not allocated yet!
00527     // Requires an accurate mpParent pointer.
00534     DllExport void BuildNormals ();
00535 
00536     // This method just recomputes the directions of non-explicit normals,
00537     // without rebuilding the normal list.
00538     // Requires an accurate mpParent pointer.
00544     DllExport void ComputeNormals ();
00545 
00546     // This checks our flags and calls BuildNormals, ComputeNormals as needed.
00547     // Requires an accurate mpParent pointer.
00553     DllExport void CheckNormals ();
00554 
00555     // operators and debug printing
00560     DllExport MNNormalSpec & operator= (const MNNormalSpec & from);
00567     DllExport void CopySpecified (const MNNormalSpec & from);   // Like operator=, but omits unspecified.
00574     DllExport MNNormalSpec & operator+= (const MNNormalSpec & from);
00629     DllExport void MNDebugPrint (bool printAll=false);
00643     DllExport bool CheckAllData (int numParentFaces);
00644 
00648     DllExport IOResult Save (ISave *isave);
00652     DllExport IOResult Load (ILoad *iload);
00653 
00654     // From BaseInterface:
00655     Interface_ID GetID() {return MN_NORMAL_SPEC_INTERFACE;}
00656     DllExport void DeleteInterface();
00657     DllExport BaseInterface* GetInterface(Interface_ID id);
00658     DllExport BaseInterface* CloneInterface(void* remapDir = NULL);
00659 
00660     // --- IPipelineClient methods
00661     DllExport void ShallowCopy( IPipelineClient* from, ChannelMask channels );
00662     DllExport void DeepCopy( IPipelineClient* from, ChannelMask channels );
00663     DllExport void NewAndCopyChannels( ChannelMask channels );
00664     DllExport void FreeChannels( ChannelMask channels, int zeroOthers = 1 );
00665     DllExport void ZeroChannels( ChannelMask channels );
00666     DllExport void AppendAllChannels( IPipelineClient* from );
00667 
00668     // Actual operations:
00695     DllExport bool Transform (Matrix3 & xfm, BOOL useSel=false, BitArray *normalSelection=NULL);
00722     DllExport bool Translate (Point3 & translate, BOOL useSel=true, BitArray *normalSelection=NULL);
00743     DllExport bool BreakNormals (BOOL useSel=true, BitArray *normalSelection=NULL, BOOL toAverage=false);
00744     // Requires an accurate mpParent pointer:
00773     DllExport bool UnifyNormals (BOOL useSel=true, BitArray *normalSelection=NULL, BOOL toAverage=false);
00774     DllExport bool AverageNormals (BOOL useThresh=false, float threshold=0.0f, BOOL useSel=true, BitArray *normalSelection=NULL);
00795     DllExport bool SpecifyNormals (BOOL useSel=true, BitArray *normalSelection=NULL);
00822     DllExport bool MakeNormalsExplicit (BOOL useSel=true, BitArray *normalSelection=NULL, bool value=true);
00844     DllExport bool ResetNormals (BOOL useSel=true, BitArray *normalSelection=NULL);
00845 };
00846