1 #pragma once 2 3 #include "lc_math.h" 4 #include "lc_commands.h" 5 #include "lc_array.h" 6 7 #define LC_SEL_NO_PIECES 0x0001 // No pieces in model 8 #define LC_SEL_PIECE 0x0002 // At last 1 piece selected 9 #define LC_SEL_SELECTED 0x0004 // At last 1 object selected 10 #define LC_SEL_UNSELECTED 0x0008 // At least 1 piece unselected 11 #define LC_SEL_HIDDEN 0x0010 // At least one piece hidden 12 #define LC_SEL_HIDDEN_SELECTED 0x0020 // At least one piece selected is hidden 13 #define LC_SEL_VISIBLE_SELECTED 0x0040 // At least one piece selected is not hidden 14 #define LC_SEL_GROUPED 0x0080 // At least one piece selected is grouped 15 #define LC_SEL_FOCUS_GROUPED 0x0100 // Focused piece is grouped 16 #define LC_SEL_CAN_GROUP 0x0200 // Can make a new group 17 #define LC_SEL_MODEL_SELECTED 0x0400 // At least one model reference is selected 18 #define LC_SEL_CAN_ADD_CONTROL_POINT 0x0800 // Can add control points to focused piece 19 #define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x1000 // Can remove control points from focused piece 20 21 enum class lcSelectionMode 22 { 23 Single, 24 Piece, 25 Color, 26 PieceColor 27 }; 28 29 enum class lcTransformType 30 { 31 First, 32 AbsoluteTranslation = First, 33 RelativeTranslation, 34 AbsoluteRotation, 35 RelativeRotation, 36 Count 37 }; 38 39 class lcModelProperties 40 { 41 public: 42 void LoadDefaults(); 43 void SaveDefaults(); 44 45 bool operator==(const lcModelProperties& Properties) const 46 { 47 if (mFileName != Properties.mFileName || mModelName != Properties.mModelName || mAuthor != Properties.mAuthor || 48 mDescription != Properties.mDescription || mComments != Properties.mComments) 49 return false; 50 51 if (mAmbientColor != Properties.mAmbientColor) 52 return false; 53 54 return true; 55 } 56 57 void SaveLDraw(QTextStream& Stream) const; 58 bool ParseLDrawHeader(QString Line, bool FirstLine); 59 void ParseLDrawLine(QTextStream& Stream); 60 61 QString mFileName; 62 QString mDescription; 63 QString mModelName; 64 QString mAuthor; 65 QString mComments; 66 67 lcVector3 mAmbientColor; 68 }; 69 70 struct lcModelHistoryEntry 71 { 72 QByteArray File; 73 QString Description; 74 }; 75 76 class lcModel 77 { 78 public: 79 lcModel(const QString& FileName, Project* Project, bool Preview); 80 ~lcModel(); 81 82 lcModel(const lcModel&) = delete; 83 lcModel& operator=(const lcModel&) = delete; 84 GetProject()85 Project* GetProject() const 86 { 87 return mProject; 88 } 89 IsModified()90 bool IsModified() const 91 { 92 return mSavedHistory != mUndoHistory[0]; 93 } 94 IsActive()95 bool IsActive() const 96 { 97 return mActive; 98 } 99 100 bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const; 101 bool IncludesModel(const lcModel* Model) const; 102 void CreatePieceInfo(Project* Project); 103 void UpdatePieceInfo(std::vector<lcModel*>& UpdatedModels); 104 void UpdateMesh(); 105 void UpdateAllViews() const; 106 GetPieceInfo()107 PieceInfo* GetPieceInfo() const 108 { 109 return mPieceInfo; 110 } 111 GetPieces()112 const lcArray<lcPiece*>& GetPieces() const 113 { 114 return mPieces; 115 } 116 GetCameras()117 const lcArray<lcCamera*>& GetCameras() const 118 { 119 return mCameras; 120 } 121 GetLights()122 const lcArray<lcLight*>& GetLights() const 123 { 124 return mLights; 125 } 126 GetGroups()127 const lcArray<lcGroup*>& GetGroups() const 128 { 129 return mGroups; 130 } 131 GetProperties()132 const lcModelProperties& GetProperties() const 133 { 134 return mProperties; 135 } 136 SetFileName(const QString & FileName)137 void SetFileName(const QString& FileName) 138 { 139 if (mProperties.mModelName == mProperties.mFileName) 140 mProperties.mModelName = FileName; 141 mProperties.mFileName = FileName; 142 } 143 GetFileName()144 const QString& GetFileName() const 145 { 146 return mProperties.mFileName; 147 } 148 SetDescription(const QString & Description)149 void SetDescription(const QString& Description) 150 { 151 mProperties.mDescription = Description; 152 } 153 GetFileLines()154 const QStringList& GetFileLines() const 155 { 156 return mFileLines; 157 } 158 159 lcStep GetLastStep() const; 160 GetCurrentStep()161 lcStep GetCurrentStep() const 162 { 163 return mCurrentStep; 164 } 165 166 void SetActive(bool Active); 167 void CalculateStep(lcStep Step); 168 void SetCurrentStep(lcStep Step); SetTemporaryStep(lcStep Step)169 void SetTemporaryStep(lcStep Step) 170 { 171 mCurrentStep = Step; 172 CalculateStep(Step); 173 } 174 175 void ShowFirstStep(); 176 void ShowLastStep(); 177 void ShowPreviousStep(); 178 void ShowNextStep(); 179 void InsertStep(lcStep Step); 180 void RemoveStep(lcStep Step); 181 182 void AddPiece(); 183 void DeleteAllCameras(); 184 void DeleteSelectedObjects(); 185 void ResetSelectedPiecesPivotPoint(); 186 void RemoveSelectedPiecesKeyFrames(); 187 void InsertControlPoint(); 188 void RemoveFocusedControlPoint(); 189 void ShowSelectedPiecesEarlier(); 190 void ShowSelectedPiecesLater(); 191 void SetPieceSteps(const QList<QPair<lcPiece*, lcStep>>& PieceSteps); 192 void RenamePiece(PieceInfo* Info); 193 194 void MoveSelectionToModel(lcModel* Model); 195 void InlineSelectedModels(); 196 197 lcGroup* AddGroup(const QString& Prefix, lcGroup* Parent); 198 lcGroup* GetGroup(const QString& Name, bool CreateIfMissing); 199 void RemoveGroup(lcGroup* Group); 200 void GroupSelection(); 201 void UngroupSelection(); 202 void AddSelectedPiecesToGroup(); 203 void RemoveFocusPieceFromGroup(); 204 void ShowEditGroupsDialog(); 205 206 void SaveLDraw(QTextStream& Stream, bool SelectedOnly) const; 207 void LoadLDraw(QIODevice& Device, Project* Project); 208 bool LoadBinary(lcFile* File); 209 bool LoadLDD(const QString& FileData); 210 bool LoadInventory(const QByteArray& Inventory); 211 int SplitMPD(QIODevice& Device); 212 void Merge(lcModel* Other); 213 SetSaved()214 void SetSaved() 215 { 216 if (mUndoHistory.empty()) 217 SaveCheckpoint(QString()); 218 219 if (!mIsPreview) 220 mSavedHistory = mUndoHistory[0]; 221 } 222 223 void SetMinifig(const lcMinifig& Minifig); 224 void SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex); 225 226 void Cut(); 227 void Copy(); 228 void Paste(bool PasteToCurrentStep); 229 void DuplicateSelectedPieces(); 230 void PaintSelectedPieces(); 231 232 void GetScene(lcScene* Scene, lcCamera* ViewCamera, bool AllowHighlight, bool AllowFade) const; 233 void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const; 234 QImage GetStepImage(bool Zoom, int Width, int Height, lcStep Step); 235 QImage GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor) const; 236 void SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, int Width, int Height, lcStep Start, lcStep End); 237 238 void RayTest(lcObjectRayTest& ObjectRayTest) const; 239 void BoxTest(lcObjectBoxTest& ObjectBoxTest) const; 240 bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance) const; 241 bool SubModelBoxTest(const lcVector4 Planes[6]) const; 242 void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const; 243 void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const; 244 HasPieces()245 bool HasPieces() const 246 { 247 return !mPieces.IsEmpty(); 248 } 249 250 bool AnyPiecesSelected() const; 251 bool AnyObjectsSelected() const; 252 lcModel* GetFirstSelectedSubmodel() const; 253 void GetSubModels(lcArray<lcModel*>& SubModels) const; 254 bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const; 255 bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const; 256 lcVector3 GetSelectionOrModelCenter() const; 257 bool GetFocusPosition(lcVector3& Position) const; 258 lcObject* GetFocusObject() const; 259 bool GetSelectionCenter(lcVector3& Center) const; 260 lcBoundingBox GetAllPiecesBoundingBox() const; 261 bool GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const; 262 std::vector<lcVector3> GetPiecesBoundingBoxPoints() const; 263 void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const; 264 void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList) const; 265 void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const; 266 void GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection, lcObject** Focus) const; 267 lcArray<lcObject*> GetSelectionModePieces(lcPiece* SelectedPiece) const; 268 269 void FocusOrDeselectObject(const lcObjectSection& ObjectSection); 270 void ClearSelection(bool UpdateInterface); 271 void ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode); 272 void ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bool EnableSelectionMode); 273 void SetSelectionAndFocus(const lcArray<lcObject*>& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode); 274 void AddToSelection(const lcArray<lcObject*>& Objects, bool EnableSelectionMode, bool UpdateInterface); 275 void RemoveFromSelection(const lcArray<lcObject*>& Objects); 276 void RemoveFromSelection(const lcObjectSection& ObjectSection); 277 void SelectAllPieces(); 278 void InvertSelection(); 279 280 void HideSelectedPieces(); 281 void HideUnselectedPieces(); 282 void UnhideSelectedPieces(); 283 void UnhideAllPieces(); 284 285 void FindReplacePiece(bool SearchForward, bool FindAll); 286 287 void UndoAction(); 288 void RedoAction(); 289 290 lcVector3 SnapPosition(const lcVector3& Delta) const; 291 lcVector3 SnapRotation(const lcVector3& Delta) const; 292 lcMatrix33 GetRelativeRotation() const; 293 GetMouseToolDistance()294 const lcVector3& GetMouseToolDistance() const 295 { 296 return mMouseToolDistance; 297 } 298 299 void BeginMouseTool(); 300 void EndMouseTool(lcTool Tool, bool Accept); 301 void InsertPieceToolClicked(const lcMatrix44& WorldMatrix); 302 void PointLightToolClicked(const lcVector3& Position); 303 void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target); 304 void UpdateSpotLightTool(const lcVector3& Position); 305 void BeginCameraTool(const lcVector3& Position, const lcVector3& Target); 306 void UpdateCameraTool(const lcVector3& Position); 307 void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag); 308 void UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag); 309 void UpdateScaleTool(const float Scale); 310 void EraserToolClicked(lcObject* Object); 311 void PaintToolClicked(lcObject* Object); 312 void ColorPickerToolClicked(lcObject* Object); 313 void UpdateZoomTool(lcCamera* Camera, float Mouse); 314 void UpdatePanTool(lcCamera* Camera, const lcVector3& Distance); 315 void UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY); 316 void UpdateRollTool(lcCamera* Camera, float Mouse); 317 void ZoomRegionToolClicked(lcCamera* Camera, float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners); 318 void LookAt(lcCamera* Camera); 319 void MoveCamera(lcCamera* Camera, const lcVector3& Direction); 320 void ZoomExtents(lcCamera* Camera, float Aspect); 321 void Zoom(lcCamera* Camera, float Amount); 322 MoveSelectedObjects(const lcVector3 & Distance,bool AllowRelative,bool AlternateButtonDrag,bool Update,bool Checkpoint)323 void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint) 324 { 325 MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint); 326 } 327 328 void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint); 329 void RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint); 330 void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint); 331 void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform); 332 void SetSelectedPiecesColorIndex(int ColorIndex); 333 void SetSelectedPiecesPieceInfo(PieceInfo* Info); 334 void SetSelectedPiecesStepShow(lcStep Step); 335 void SetSelectedPiecesStepHide(lcStep Step); 336 337 void SetCameraOrthographic(lcCamera* Camera, bool Ortho); 338 void SetCameraFOV(lcCamera* Camera, float FOV); 339 void SetCameraZNear(lcCamera* Camera, float ZNear); 340 void SetCameraZFar(lcCamera* Camera, float ZFar); 341 void SetCameraName(lcCamera* Camera, const QString& Name); 342 343 void ShowPropertiesDialog(); 344 void ShowSelectByNameDialog(); 345 void ShowArrayDialog(); 346 void ShowMinifigDialog(); 347 void UpdateInterface(); 348 349 protected: 350 void DeleteModel(); 351 void DeleteHistory(); 352 void SaveCheckpoint(const QString& Description); 353 void LoadCheckPoint(lcModelHistoryEntry* CheckPoint); 354 355 QString GetGroupName(const QString& Prefix); 356 void RemoveEmptyGroups(); 357 bool RemoveSelectedObjects(); 358 359 void SelectGroup(lcGroup* TopGroup, bool Select); 360 361 void AddPiece(lcPiece* Piece); 362 void InsertPiece(lcPiece* Piece, int Index); 363 364 lcModelProperties mProperties; 365 Project* const mProject; 366 PieceInfo* mPieceInfo; 367 368 bool mIsPreview; 369 bool mActive; 370 lcStep mCurrentStep; 371 lcVector3 mMouseToolDistance; 372 373 lcArray<lcPiece*> mPieces; 374 lcArray<lcCamera*> mCameras; 375 lcArray<lcLight*> mLights; 376 lcArray<lcGroup*> mGroups; 377 QStringList mFileLines; 378 379 lcModelHistoryEntry* mSavedHistory; 380 std::vector<lcModelHistoryEntry*> mUndoHistory; 381 std::vector<lcModelHistoryEntry*> mRedoHistory; 382 383 Q_DECLARE_TR_FUNCTIONS(lcModel); 384 }; 385