1 #ifndef __LDLMODEL_H__ 2 #define __LDLMODEL_H__ 3 4 #include <TCFoundation/TCAlertSender.h> 5 #include <LDLoader/LDLFileLine.h> 6 #include <LDLoader/LDLError.h> 7 #include <stdio.h> 8 #include <stdarg.h> 9 #include <fstream> 10 11 class TCDictionary; 12 class LDLMainModel; 13 class LDLCommentLine; 14 class LDLModelLine; 15 class TCImage; 16 17 typedef enum 18 { 19 // WARNING: Increasing this list past 4 members requires more bits in flags. 20 // Note that even now, it requires 3 bits, because the compiler treats it 21 // as a signed integer. When the value 2 is sign-extended, it becomes -2, 22 // which doesn't match. 23 BFCUnknownState, 24 BFCOffState, 25 BFCOnState, 26 BFCForcedOnState 27 } BFCState; 28 29 typedef bool (*LDLFileCaseCallback)(char *filename); 30 typedef void (TCObject::*LDLScanPointCallback)(const TCVector &point, 31 const LDLFileLine *pFileLine); 32 struct LDrawIniS; 33 34 class LDLModel : public TCAlertSender 35 { 36 public: 37 LDLModel(void); 38 LDLModel(const LDLModel &other); 39 virtual TCObject *copy(void) const; 40 // Color numbers might become dynamic, so not static. 41 virtual void getRGBA(int colorNumber, int& r, int& g, int& b, int& a); 42 virtual TCULong getPackedRGBA(int colorNumber); 43 virtual int getEdgeColorNumber(int colorNumber); 44 virtual bool hasSpecular(int colorNumber); 45 virtual bool hasShininess(int colorNumber); 46 virtual void getSpecular(int colorNumber, float *specular); 47 virtual void getShininess(int colorNumber, float &shininess); 48 virtual LDLModel *subModelNamed(const char *subModelName, 49 bool lowRes = false, bool secondAttempt = false, 50 const LDLModelLine *fileLine = NULL, bool knownPart = false); getFilename(void)51 virtual const char *getFilename(void) const { return m_filename; } 52 virtual void setFilename(const char *filename); getName(void)53 virtual const char *getName(void) const { return m_name; } getDescription(void)54 virtual const char *getDescription(void) const { return m_description; } getAuthor(void)55 virtual const char *getAuthor(void) const { return m_author; } 56 virtual void setName(const char *name); 57 bool load(std::ifstream &stream, bool trackProgress = true); 58 void print(int indent) const; 59 virtual bool parse(void); 60 virtual TCDictionary* getLoadedModels(void); 61 virtual bool getLowResStuds(void) const; 62 virtual LDLError *newError(LDLErrorType type, const LDLFileLine &fileLine, 63 CUCSTR format, va_list argPtr); 64 virtual LDLError *newError(LDLErrorType type, const LDLFileLine &fileLine, 65 CUCSTR format, ...); 66 virtual LDLError *newError(LDLErrorType type, CUCSTR format, 67 va_list argPtr); 68 virtual LDLError *newError(LDLErrorType type, CUCSTR format, ...); 69 virtual LDLFileLineArray *getFileLines(bool initialize = false); getFileLines(void)70 virtual const LDLFileLineArray *getFileLines(void) const 71 { 72 return m_fileLines; 73 } getStepIndices(void)74 virtual const IntList &getStepIndices(void) const { return m_stepIndices; } getActiveLineCount(void)75 virtual int getActiveLineCount(void) const { return m_activeLineCount; } setActiveLineCount(int value)76 virtual void setActiveLineCount(int value) { m_activeLineCount = value; } 77 virtual bool colorNumberIsTransparent(int colorNumber); isMainModel(void)78 virtual bool isMainModel(void) const { return false; } 79 virtual void scanPoints(TCObject *scanner, 80 LDLScanPointCallback scanPointCallback, const TCFloat *matrix, 81 int step = -1, bool watchBBoxIgnore = false) const; 82 virtual void getBoundingBox(TCVector &min, TCVector &max) const; 83 virtual TCFloat getMaxRadius(const TCVector ¢er, bool watchBBoxIgnore); 84 85 // Flags 86 // Note that bit flags can cause odd results; thus returning the != false, 87 // instead of returning the flag value directly. isPart(void)88 bool isPart(void) const { return m_flags.part != false; } isPrimitive(void)89 bool isPrimitive(void) const { return m_flags.primitive != false; } isSubPart(void)90 bool isSubPart(void) const { return m_flags.subPart != false; } isMPD(void)91 bool isMPD(void) const { return m_flags.mpd != false; } getNoShrinkFlag(void)92 bool getNoShrinkFlag(void) const { return m_flags.noShrink != false; } setNoShrinkFlag(bool value)93 void setNoShrinkFlag(bool value) { m_flags.noShrink = value; } isOfficial(void)94 bool isOfficial(void) const { return m_flags.official != false; } isUnOfficial(void)95 bool isUnOfficial(void) const { return m_flags.unofficial != false; } hasStuds(void)96 bool hasStuds(void) const { return m_flags.hasStuds != false; } 97 bool hasBoundingBox(void) const; 98 void copyPublicFlags(const LDLModel *src); 99 void copyBoundingBox(const LDLModel *src); 100 bool searchNext(const std::string &searchString, IntVector& path, 101 int loopEnd, TCULong activeLineTypes) const; 102 bool searchPrevious(const std::string &searchString, IntVector& path, 103 int loopEnd, TCULong activeLineTypes) const; 104 //bool hasBoundingBox(void) const { return m_flags.haveBoundingBox != false; } 105 106 getBFCState(void)107 BFCState getBFCState(void) { return m_flags.bfcCertify; } 108 getBFCOn(void)109 bool getBFCOn(void) 110 { 111 return m_flags.bfcCertify == BFCOnState || 112 m_flags.bfcCertify == BFCForcedOnState; 113 } 114 115 virtual void cancelLoad(void); 116 virtual bool getLoadCanceled(void); getMainModel(void)117 LDLMainModel *getMainModel(void) { return m_mainModel; } setMainModel(LDLMainModel * value)118 void setMainModel(LDLMainModel *value) { m_mainModel = value; } getMainModel(void)119 const LDLMainModel *getMainModel(void) const { return m_mainModel; } 120 virtual TCObject *getAlertSender(void); 121 virtual int loadMpdTexmaps(void); 122 123 static const char *lDrawDir(bool defaultValue = false); 124 static void setLDrawDir(const char *value); 125 static void setFileCaseCallback(LDLFileCaseCallback value); getFileCaseCallback(void)126 static LDLFileCaseCallback getFileCaseCallback(void) 127 { 128 return fileCaseCallback; 129 } 130 static bool openFile(const char *filename, std::ifstream &modelStream); 131 static bool openStream(const char *filename, std::ifstream &stream); 132 static void combinePathParts(std::string &path, const std::string &left, 133 const std::string& middle, const std::string &right = std::string()); 134 protected: 135 virtual void dealloc(void); 136 bool openTexmap(const char *filename, std::ifstream &texmapStream, 137 std::string &path); 138 virtual bool openSubModelNamed(const char* subModelName, 139 std::string &subModelPath, std::ifstream &fileStream, bool knownPart, 140 bool *pLoop = NULL, bool isText = true); 141 virtual bool initializeNewSubModel(LDLModel* subModel, 142 const char *dictName, std::ifstream &subModelStream); 143 virtual bool initializeNewSubModel(LDLModel* subModel, 144 const char *dictName); 145 virtual bool read(std::ifstream &stream); 146 virtual int parseComment(int index, LDLCommentLine *commentLine); 147 virtual int parseMPDMeta(int index, const char *filename); 148 virtual int parseBFCMeta(LDLCommentLine *commentLine); 149 virtual int parseTexmapMeta(LDLCommentLine *commentLine); 150 virtual int parseBBoxIgnoreMeta(LDLCommentLine *commentLine); 151 virtual void readComment(LDLCommentLine *commentLine); 152 virtual void sendAlert(LDLError *alert); 153 virtual void sendAlert(LDLErrorType type, LDLAlertLevel level, 154 CUCSTR format, va_list argPtr); 155 virtual void sendAlert(LDLErrorType type, LDLAlertLevel level, 156 const LDLFileLine &fileLine, CUCSTR format, va_list argPtr); 157 virtual void reportError(LDLErrorType type, const LDLFileLine &fileLine, 158 CUCSTR format, ...); 159 virtual void reportWarning(LDLErrorType type, const LDLFileLine &fileLine, 160 CUCSTR format, ...); 161 virtual void reportError(LDLErrorType type, CUCSTR format, ...); 162 virtual void reportWarning(LDLErrorType type, CUCSTR format, ...); 163 virtual void reportProgress(const char *message, float progress, 164 bool mainOnly = true); 165 virtual void reportProgress(const wchar_t *message, float progress, 166 bool mainOnly = true); 167 virtual bool isSubPart(const char *subModelName); 168 virtual bool isAbsolutePath(const char *path); 169 // virtual void processModelLine(LDLModelLine *modelLine); 170 virtual bool openModelFile(const char *filename, std::ifstream &modelStream, 171 bool isText, bool knownPart = false); 172 virtual void calcBoundingBox(void) const; 173 virtual void calcMaxRadius(const TCVector ¢er, bool watchBBoxIgnore); 174 void scanBoundingBoxPoint(const TCVector &point, LDLFileLine *pFileLine); 175 void scanRadiusSquaredPoint(const TCVector &point, LDLFileLine *pFileLine); 176 void sendUnofficialWarningIfPart(const LDLModel *subModel, 177 const LDLModelLine *fileLine, const char *subModelName); 178 void endTexmap(void); 179 void extractData(); 180 181 static bool verifyLDrawDir(const char *value); 182 static void initCheckDirs(); 183 184 char *m_filename; 185 char *m_name; 186 char *m_author; 187 char *m_description; 188 LDLFileLineArray *m_fileLines; 189 LDLModelArray *m_mpdTexmapModels; 190 LDLCommentLineArray *m_mpdTexmapLines; 191 TCImageArray *m_mpdTexmapImages; 192 LDLMainModel *m_mainModel; 193 IntList m_stepIndices; 194 int m_activeLineCount; 195 LDLModel *m_activeMPDModel; 196 197 TCVector m_boundingMin; 198 TCVector m_boundingMax; 199 TCVector m_center; 200 TCFloat m_maxRadius; 201 TCFloat m_maxFullRadius; 202 std::string m_texmapFilename; 203 TCImage *m_texmapImage; 204 LDLFileLine::TexmapType m_texmapType; 205 TCVector m_texmapPoints[3]; 206 TCFloat m_texmapExtra[2]; 207 std::vector<TCByte> m_data; 208 LDLCommentLine *m_dataLine; 209 struct 210 { 211 // Private flags 212 bool loadingPart:1; // Temporal 213 bool loadingSubPart:1; // Temporal 214 bool loadingPrimitive:1; // Temporal 215 bool loadingUnoffic:1; // Temporal 216 bool mainModelLoaded:1; // Temporal 217 bool mainModelParsed:1; // Temporal 218 bool started:1; // Temporal 219 bool bfcClip:1; // Temporal 220 bool bfcWindingCCW:1; // Temporal 221 bool bfcInvertNext:1; // Temporal 222 bool haveBoundingBox:1; // Temporal 223 bool haveMaxRadius:1; // Temporal 224 bool haveMaxFullRadius:1; // Temporal 225 bool fullRadius:1; // Temporal 226 bool texmapStarted:1; // Temporal 227 bool texmapFallback:1; // Temporal 228 bool texmapNext:1; // Temporal 229 bool texmapValid:1; // Temporal 230 // Public flags 231 bool part:1; 232 bool subPart:1; 233 bool primitive:1; 234 bool mpd:1; 235 bool noShrink:1; 236 bool official:1; 237 bool unofficial:1; 238 bool hasStuds:1; 239 BFCState bfcCertify:3; 240 bool bboxIgnoreOn:1; 241 bool bboxIgnoreBegun:1; 242 } m_flags; 243 244 static StringList sm_checkDirs; 245 static char *sm_systemLDrawDir; 246 static char *sm_defaultLDrawDir; 247 static LDrawIniS *sm_lDrawIni; 248 static int sm_modelCount; 249 static LDLFileCaseCallback fileCaseCallback; 250 static class LDLModelCleanup 251 { 252 public: 253 ~LDLModelCleanup(void); 254 } sm_cleanup; 255 friend class LDLModelCleanup; 256 }; 257 258 #endif // __LDLMODEL_H__ 259