leocad/common/lc_model.h

418 lines
14 KiB
C
Raw Normal View History

#pragma once
2016-10-05 23:28:52 +02:00
#include "lc_math.h"
#include "lc_commands.h"
2024-01-21 21:53:18 +01:00
enum class lcObjectPropertyId;
2016-10-05 23:28:52 +02:00
#define LC_SEL_NO_PIECES 0x0001 // No pieces in model
2023-09-04 19:59:16 +02:00
#define LC_SEL_PIECE 0x0002 // At least 1 piece selected
#define LC_SEL_CAMERA 0x0004 // At least 1 camera selected
#define LC_SEL_LIGHT 0x0008 // At least 1 light selected
#define LC_SEL_SELECTED 0x0010 // At least 1 object selected
#define LC_SEL_UNSELECTED 0x0020 // At least 1 piece unselected
#define LC_SEL_HIDDEN 0x0040 // At least one piece hidden
#define LC_SEL_HIDDEN_SELECTED 0x0080 // At least one piece selected is hidden
#define LC_SEL_VISIBLE_SELECTED 0x0100 // At least one piece selected is not hidden
#define LC_SEL_GROUPED 0x0200 // At least one piece selected is grouped
#define LC_SEL_FOCUS_GROUPED 0x0400 // Focused piece is grouped
#define LC_SEL_CAN_GROUP 0x0800 // Can make a new group
#define LC_SEL_MODEL_SELECTED 0x1000 // At least one model reference is selected
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x2000 // Can add control points to focused piece
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x4000 // Can remove control points from focused piece
2016-10-05 23:28:52 +02:00
2017-11-22 02:58:36 +01:00
enum class lcSelectionMode
{
2020-05-03 22:04:40 +02:00
Single,
Piece,
Color,
PieceColor
2017-11-22 02:58:36 +01:00
};
2020-05-03 22:04:40 +02:00
enum class lcTransformType
2016-10-05 23:28:52 +02:00
{
2020-05-03 22:04:40 +02:00
First,
AbsoluteTranslation = First,
RelativeTranslation,
AbsoluteRotation,
RelativeRotation,
Count
2016-10-05 23:28:52 +02:00
};
class lcModelProperties
{
public:
void LoadDefaults();
void SaveDefaults();
bool operator==(const lcModelProperties& Properties) const
2016-10-05 23:28:52 +02:00
{
2020-05-03 21:11:51 +02:00
if (mFileName != Properties.mFileName || mModelName != Properties.mModelName || mAuthor != Properties.mAuthor ||
2016-10-05 23:28:52 +02:00
mDescription != Properties.mDescription || mComments != Properties.mComments)
return false;
2017-04-21 23:17:03 +02:00
if (mAmbientColor != Properties.mAmbientColor)
2016-10-05 23:28:52 +02:00
return false;
return true;
}
void SaveLDraw(QTextStream& Stream) const;
2020-05-03 21:11:51 +02:00
bool ParseLDrawHeader(QString Line, bool FirstLine);
2016-10-05 23:28:52 +02:00
void ParseLDrawLine(QTextStream& Stream);
2020-05-03 21:11:51 +02:00
QString mFileName;
2016-10-05 23:28:52 +02:00
QString mDescription;
2020-05-03 21:11:51 +02:00
QString mModelName;
QString mAuthor;
2016-10-05 23:28:52 +02:00
QString mComments;
lcVector3 mAmbientColor;
};
2023-08-09 12:35:07 +02:00
class lcPOVRayOptions
{
public:
void ParseLDrawLine(QTextStream& LineStream);
void SaveLDraw(QTextStream& Stream) const;
bool UseLGEO = false;
bool ExcludeFloor = false;
bool ExcludeBackground = false;
bool NoReflection = false;
bool NoShadow = false;
int FloorAxis = 1;
float FloorAmbient = 0.4f;
float FloorDiffuse = 0.4f;
lcVector3 FloorColor = lcVector3(0.8f,0.8f,0.8f);
2023-08-09 12:35:07 +02:00
QString HeaderIncludeFile;
QString FooterIncludeFile;
};
2016-10-05 23:28:52 +02:00
struct lcModelHistoryEntry
{
QByteArray File;
QString Description;
};
class lcModel
{
public:
2020-12-16 02:19:32 +01:00
lcModel(const QString& FileName, Project* Project, bool Preview);
2016-10-05 23:28:52 +02:00
~lcModel();
2020-05-04 00:39:39 +02:00
lcModel(const lcModel&) = delete;
2021-11-15 03:34:24 +01:00
lcModel(lcModel&&) = delete;
2020-05-04 00:39:39 +02:00
lcModel& operator=(const lcModel&) = delete;
2021-11-15 03:34:24 +01:00
lcModel& operator=(lcModel&&) = delete;
2020-12-16 02:19:32 +01:00
Project* GetProject() const
{
return mProject;
}
2020-05-04 00:39:39 +02:00
2016-10-05 23:28:52 +02:00
bool IsModified() const
{
return mSavedHistory != mUndoHistory[0];
}
bool IsActive() const
{
return mActive;
}
bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const;
2016-10-05 23:28:52 +02:00
bool IncludesModel(const lcModel* Model) const;
void CreatePieceInfo(Project* Project);
2019-03-17 21:27:57 +01:00
void UpdatePieceInfo(std::vector<lcModel*>& UpdatedModels);
void UpdateMesh();
2020-12-16 02:19:32 +01:00
void UpdateAllViews() const;
2016-10-05 23:28:52 +02:00
PieceInfo* GetPieceInfo() const
{
return mPieceInfo;
}
2024-06-20 04:22:18 +02:00
const std::vector<std::unique_ptr<lcPiece>>& GetPieces() const
2016-10-05 23:28:52 +02:00
{
return mPieces;
}
2024-06-04 18:34:38 +02:00
const std::vector<std::unique_ptr<lcCamera>>& GetCameras() const
2016-10-05 23:28:52 +02:00
{
return mCameras;
}
2024-06-04 18:08:54 +02:00
const std::vector<std::unique_ptr<lcLight>>& GetLights() const
2016-10-05 23:28:52 +02:00
{
return mLights;
}
const std::vector<std::unique_ptr<lcGroup>>& GetGroups() const
2016-10-05 23:28:52 +02:00
{
return mGroups;
}
const lcModelProperties& GetProperties() const
{
return mProperties;
}
2023-08-09 12:35:07 +02:00
const lcPOVRayOptions& GetPOVRayOptions() const
{
return mPOVRayOptions;
}
2020-05-03 21:11:51 +02:00
void SetFileName(const QString& FileName)
2016-10-05 23:28:52 +02:00
{
2020-05-03 21:11:51 +02:00
if (mProperties.mModelName == mProperties.mFileName)
mProperties.mModelName = FileName;
mProperties.mFileName = FileName;
2016-10-05 23:28:52 +02:00
}
2020-05-03 21:11:51 +02:00
const QString& GetFileName() const
{
2020-05-03 21:11:51 +02:00
return mProperties.mFileName;
}
2017-08-20 22:47:53 +02:00
void SetDescription(const QString& Description)
{
mProperties.mDescription = Description;
}
2016-10-05 23:28:52 +02:00
const QStringList& GetFileLines() const
{
return mFileLines;
}
lcStep GetLastStep() const;
lcStep GetCurrentStep() const
{
return mCurrentStep;
}
void SetActive(bool Active);
void CalculateStep(lcStep Step);
void SetCurrentStep(lcStep Step);
void SetTemporaryStep(lcStep Step)
{
mCurrentStep = Step;
CalculateStep(Step);
}
void ShowFirstStep();
void ShowLastStep();
void ShowPreviousStep();
void ShowNextStep();
void InsertStep(lcStep Step);
void RemoveStep(lcStep Step);
void AddPiece();
void DeleteAllCameras();
void DeleteSelectedObjects();
void ResetSelectedPiecesPivotPoint();
void RemoveSelectedPiecesKeyFrames();
2016-10-05 23:28:52 +02:00
void InsertControlPoint();
void RemoveFocusedControlPoint();
void ShowSelectedPiecesEarlier();
void ShowSelectedPiecesLater();
2024-06-20 04:22:18 +02:00
void SetPieceSteps(const std::vector<std::pair<lcPiece*, lcStep>>& PieceSteps);
2017-07-24 04:35:18 +02:00
void RenamePiece(PieceInfo* Info);
2016-10-05 23:28:52 +02:00
void MoveSelectionToModel(lcModel* Model);
void InlineSelectedModels();
lcGroup* AddGroup(const QString& Prefix, lcGroup* Parent);
lcGroup* GetGroup(const QString& Name, bool CreateIfMissing);
void RemoveGroup(lcGroup* Group);
void GroupSelection();
void UngroupSelection();
void AddSelectedPiecesToGroup();
void RemoveFocusPieceFromGroup();
void ShowEditGroupsDialog();
2023-06-19 03:37:59 +02:00
void SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep LastStep) const;
2016-10-05 23:28:52 +02:00
void LoadLDraw(QIODevice& Device, Project* Project);
bool LoadBinary(lcFile* File);
2017-06-26 03:20:34 +02:00
bool LoadLDD(const QString& FileData);
2017-08-20 22:47:53 +02:00
bool LoadInventory(const QByteArray& Inventory);
int SplitMPD(QIODevice& Device);
2016-10-05 23:28:52 +02:00
void Merge(lcModel* Other);
void SetSaved()
{
2019-06-24 03:28:14 +02:00
if (mUndoHistory.empty())
2016-10-05 23:28:52 +02:00
SaveCheckpoint(QString());
if (!mIsPreview)
mSavedHistory = mUndoHistory[0];
}
void SetMinifig(const lcMinifig& Minifig);
2021-01-09 00:11:02 +01:00
void SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex);
2016-10-05 23:28:52 +02:00
void Cut();
void Copy();
void Paste(bool PasteToCurrentStep);
2017-03-09 00:49:57 +01:00
void DuplicateSelectedPieces();
void PaintSelectedPieces();
2016-10-05 23:28:52 +02:00
2021-11-15 03:34:24 +01:00
void GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHighlight, bool AllowFade) const;
2020-12-05 20:02:10 +01:00
void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const;
QImage GetStepImage(bool Zoom, int Width, int Height, lcStep Step);
2021-01-16 23:43:24 +01:00
QImage GetPartsListImage(int MaxWidth, lcStep Step, quint32 BackgroundColor, QFont Font, QColor TextColor) const;
void SaveStepImages(const QString& BaseName, bool AddStepSuffix, bool Zoom, int Width, int Height, lcStep Start, lcStep End);
2016-10-05 23:28:52 +02:00
void RayTest(lcObjectRayTest& ObjectRayTest) const;
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const;
bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const;
2016-10-05 23:28:52 +02:00
bool SubModelBoxTest(const lcVector4 Planes[6]) const;
void SubModelCompareBoundingBox(const lcMatrix44& WorldMatrix, lcVector3& Min, lcVector3& Max) const;
void SubModelAddBoundingBoxPoints(const lcMatrix44& WorldMatrix, std::vector<lcVector3>& Points) const;
2016-10-05 23:28:52 +02:00
bool HasPieces() const
{
2024-05-26 22:01:34 +02:00
return !mPieces.empty();
}
2016-10-05 23:28:52 +02:00
bool AnyPiecesSelected() const;
bool AnyObjectsSelected() const;
lcModel* GetFirstSelectedSubmodel() const;
2024-06-17 02:43:02 +02:00
void GetSubModels(std::set<lcModel*>& SubModels) const;
2016-10-05 23:28:52 +02:00
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
2023-09-04 19:59:16 +02:00
bool CanRotateSelection() const;
2016-10-05 23:28:52 +02:00
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
lcVector3 GetSelectionOrModelCenter() const;
bool GetFocusPosition(lcVector3& Position) const;
lcObject* GetFocusObject() const;
bool GetSelectionCenter(lcVector3& Center) const;
2021-03-01 00:57:02 +01:00
lcBoundingBox GetAllPiecesBoundingBox() const;
bool GetVisiblePiecesBoundingBox(lcVector3& Min, lcVector3& Max) const;
std::vector<lcVector3> GetPiecesBoundingBoxPoints() const;
void GetPartsList(int DefaultColorIndex, bool ScanSubModels, bool AddSubModels, lcPartsList& PartsList) const;
2023-06-19 03:37:59 +02:00
void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList, bool Cumulative) const;
2019-05-28 01:39:51 +02:00
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;
2024-05-15 05:45:09 +02:00
void GetSelectionInformation(int* Flags, std::vector<lcObject*>& Selection, lcObject** Focus) const;
2024-05-26 22:01:34 +02:00
std::vector<lcObject*> GetSelectionModePieces(const lcPiece* SelectedPiece) const;
2016-10-05 23:28:52 +02:00
void FocusOrDeselectObject(const lcObjectSection& ObjectSection);
void ClearSelection(bool UpdateInterface);
2017-12-02 21:22:04 +01:00
void ClearSelectionAndSetFocus(lcObject* Object, quint32 Section, bool EnableSelectionMode);
2017-11-22 02:58:36 +01:00
void ClearSelectionAndSetFocus(const lcObjectSection& ObjectSection, bool EnableSelectionMode);
2024-05-26 22:01:34 +02:00
void SetSelectionAndFocus(const std::vector<lcObject*>& Selection, lcObject* Focus, quint32 Section, bool EnableSelectionMode);
void AddToSelection(const std::vector<lcObject*>& Objects, bool EnableSelectionMode, bool UpdateInterface);
void RemoveFromSelection(const std::vector<lcObject*>& Objects);
void RemoveFromSelection(const lcObjectSection& ObjectSection);
2016-10-05 23:28:52 +02:00
void SelectAllPieces();
void InvertSelection();
void HideSelectedPieces();
void HideUnselectedPieces();
void UnhideSelectedPieces();
void UnhideAllPieces();
void FindReplacePiece(bool SearchForward, bool FindAll, bool Replace);
2016-10-05 23:28:52 +02:00
void UndoAction();
void RedoAction();
lcVector3 SnapPosition(const lcVector3& Delta) const;
lcVector3 SnapRotation(const lcVector3& Delta) const;
lcMatrix33 GetRelativeRotation() const;
const lcVector3& GetMouseToolDistance() const
{
return mMouseToolDistance;
}
void BeginMouseTool();
void EndMouseTool(lcTool Tool, bool Accept);
2024-11-03 03:34:22 +01:00
void InsertPieceToolClicked(PieceInfo* Info, const lcMatrix44& WorldMatrix);
void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType);
2016-10-05 23:28:52 +02:00
void BeginCameraTool(const lcVector3& Position, const lcVector3& Target);
void UpdateCameraTool(const lcVector3& Position);
void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag);
2016-10-05 23:28:52 +02:00
void UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag);
void UpdateScaleTool(const float Scale);
void EraserToolClicked(lcObject* Object);
void PaintToolClicked(lcObject* Object);
2021-11-15 03:34:24 +01:00
void ColorPickerToolClicked(const lcObject* Object);
2016-10-05 23:28:52 +02:00
void UpdateZoomTool(lcCamera* Camera, float Mouse);
void UpdatePanTool(lcCamera* Camera, const lcVector3& Distance);
void UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY);
void UpdateRollTool(lcCamera* Camera, float Mouse);
void ZoomRegionToolClicked(lcCamera* Camera, float AspectRatio, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners);
void LookAt(lcCamera* Camera);
void MoveCamera(lcCamera* Camera, const lcVector3& Direction);
void ZoomExtents(lcCamera* Camera, float Aspect, const lcMatrix44& WorldMatrix);
2016-10-05 23:28:52 +02:00
void Zoom(lcCamera* Camera, float Amount);
void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove)
2016-10-05 23:28:52 +02:00
{
MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint, FirstMove);
2016-10-05 23:28:52 +02:00
}
void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove);
2023-09-04 19:59:16 +02:00
void RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint);
2016-10-05 23:28:52 +02:00
void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint);
void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform);
2024-05-15 05:45:09 +02:00
void SetObjectsKeyFrame(const std::vector<lcObject*>& Objects, lcObjectPropertyId PropertyId, bool KeyFrame);
2016-10-05 23:28:52 +02:00
void SetSelectedPiecesColorIndex(int ColorIndex);
void SetSelectedPiecesStepShow(lcStep Step);
void SetSelectedPiecesStepHide(lcStep Step);
2024-05-15 05:45:09 +02:00
void SetObjectsProperty(const std::vector<lcObject*>& Objects, lcObjectPropertyId PropertyId, QVariant Value);
2016-10-05 23:28:52 +02:00
void SetCameraOrthographic(lcCamera* Camera, bool Ortho);
void SetCameraFOV(lcCamera* Camera, float FOV);
void SetCameraZNear(lcCamera* Camera, float ZNear);
void SetCameraZFar(lcCamera* Camera, float ZFar);
2023-08-27 20:17:07 +02:00
2016-10-05 23:28:52 +02:00
void ShowPropertiesDialog();
void ShowSelectByNameDialog();
void ShowArrayDialog();
void ShowMinifigDialog();
void UpdateInterface();
protected:
void DeleteModel();
void DeleteHistory();
void SaveCheckpoint(const QString& Description);
void LoadCheckPoint(lcModelHistoryEntry* CheckPoint);
QString GetGroupName(const QString& Prefix);
void RemoveEmptyGroups();
bool RemoveSelectedObjects();
void SelectGroup(lcGroup* TopGroup, bool Select);
void AddPiece(lcPiece* Piece);
2024-06-20 04:22:18 +02:00
void InsertPiece(lcPiece* Piece, size_t Index);
2016-10-05 23:28:52 +02:00
void UpdateTrainTrackConnections(lcPiece* FocusPiece) const;
2023-08-09 12:35:07 +02:00
lcPOVRayOptions mPOVRayOptions;
2016-10-05 23:28:52 +02:00
lcModelProperties mProperties;
2020-12-16 02:19:32 +01:00
Project* const mProject;
2016-10-05 23:28:52 +02:00
PieceInfo* mPieceInfo;
bool mIsPreview;
2016-10-05 23:28:52 +02:00
bool mActive;
lcStep mCurrentStep;
lcVector3 mMouseToolDistance;
bool mMouseToolFirstMove;
2016-10-05 23:28:52 +02:00
2024-06-20 04:22:18 +02:00
std::vector<std::unique_ptr<lcPiece>> mPieces;
2024-06-04 18:34:38 +02:00
std::vector<std::unique_ptr<lcCamera>> mCameras;
2024-06-04 18:08:54 +02:00
std::vector<std::unique_ptr<lcLight>> mLights;
std::vector<std::unique_ptr<lcGroup>> mGroups;
2016-10-05 23:28:52 +02:00
QStringList mFileLines;
lcModelHistoryEntry* mSavedHistory;
2019-06-24 03:28:14 +02:00
std::vector<lcModelHistoryEntry*> mUndoHistory;
std::vector<lcModelHistoryEntry*> mRedoHistory;
2016-10-05 23:28:52 +02:00
Q_DECLARE_TR_FUNCTIONS(lcModel);
};