452 lines
16 KiB
C++
452 lines
16 KiB
C++
#pragma once
|
|
|
|
#include "lc_math.h"
|
|
#include "lc_commands.h"
|
|
|
|
enum class lcObjectPropertyId;
|
|
enum class lcCameraProjection;
|
|
struct lcModelHistoryEditState;
|
|
class lcModelHistory;
|
|
class lcModelHistorySelect;
|
|
class lcModelHistoryEdit;
|
|
class lcModelHistoryProperties;
|
|
enum class lcModelHistoryEditMerge;
|
|
|
|
#define LC_SEL_NO_PIECES 0x0001 // No pieces in model
|
|
#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
|
|
#define LC_SEL_TRAIN_TRACK_VISIBLE 0x8000 // Focused piece has train track connections
|
|
|
|
enum class lcSelectionMode
|
|
{
|
|
Single,
|
|
Piece,
|
|
Color,
|
|
PieceColor
|
|
};
|
|
|
|
enum class lcTransformType
|
|
{
|
|
First,
|
|
AbsoluteTranslation = First,
|
|
RelativeTranslation,
|
|
AbsoluteRotation,
|
|
RelativeRotation,
|
|
Count
|
|
};
|
|
|
|
struct lcInsertPieceInfo
|
|
{
|
|
PieceInfo* Info;
|
|
lcMatrix44 Transform;
|
|
int ColorIndex;
|
|
};
|
|
|
|
class lcModelProperties
|
|
{
|
|
public:
|
|
void LoadDefaults();
|
|
void SaveDefaults();
|
|
|
|
bool operator==(const lcModelProperties& Properties) const
|
|
{
|
|
if (mFileName != Properties.mFileName || mModelName != Properties.mModelName || mAuthor != Properties.mAuthor ||
|
|
mDescription != Properties.mDescription || mComments != Properties.mComments)
|
|
return false;
|
|
|
|
if (mAmbientColor != Properties.mAmbientColor)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool operator!=(const lcModelProperties& Properties) const
|
|
{
|
|
return !(*this == Properties);
|
|
}
|
|
|
|
void SaveLDraw(QTextStream& Stream) const;
|
|
bool ParseLDrawHeader(QString Line, bool FirstLine);
|
|
void ParseLDrawLine(QTextStream& Stream);
|
|
|
|
QString mFileName;
|
|
QString mDescription;
|
|
QString mModelName;
|
|
QString mAuthor;
|
|
QString mComments;
|
|
|
|
lcVector3 mAmbientColor;
|
|
};
|
|
|
|
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);
|
|
QString HeaderIncludeFile;
|
|
QString FooterIncludeFile;
|
|
};
|
|
|
|
struct lcModelHistoryEntry
|
|
{
|
|
std::vector<std::unique_ptr<lcModelHistory>> HistorySequence;
|
|
QString Description;
|
|
};
|
|
|
|
class lcModel
|
|
{
|
|
public:
|
|
lcModel(const QString& FileName, Project* Project, bool Preview);
|
|
~lcModel();
|
|
|
|
lcModel(const lcModel&) = delete;
|
|
lcModel(lcModel&&) = delete;
|
|
lcModel& operator=(const lcModel&) = delete;
|
|
lcModel& operator=(lcModel&&) = delete;
|
|
|
|
Project* GetProject() const
|
|
{
|
|
return mProject;
|
|
}
|
|
|
|
bool IsActive() const
|
|
{
|
|
return mActive;
|
|
}
|
|
|
|
bool IsModified() const;
|
|
void SetSaved();
|
|
|
|
bool GetPieceWorldMatrix(lcPiece* Piece, lcMatrix44& ParentWorldMatrix) const;
|
|
bool IncludesModel(const lcModel* Model) const;
|
|
void CreatePieceInfo(Project* Project);
|
|
void UpdatePieceInfo(std::vector<lcModel*>& UpdatedModels);
|
|
void UpdateMesh();
|
|
void UpdateAllViews() const;
|
|
|
|
PieceInfo* GetPieceInfo() const
|
|
{
|
|
return mPieceInfo;
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<lcPiece>>& GetPieces() const
|
|
{
|
|
return mPieces;
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<lcCamera>>& GetCameras() const
|
|
{
|
|
return mCameras;
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<lcLight>>& GetLights() const
|
|
{
|
|
return mLights;
|
|
}
|
|
|
|
const std::vector<std::unique_ptr<lcGroup>>& GetGroups() const
|
|
{
|
|
return mGroups;
|
|
}
|
|
|
|
const lcModelProperties& GetProperties() const
|
|
{
|
|
return mProperties;
|
|
}
|
|
|
|
const lcPOVRayOptions& GetPOVRayOptions() const
|
|
{
|
|
return mPOVRayOptions;
|
|
}
|
|
|
|
void SetFileName(const QString& FileName)
|
|
{
|
|
if (mProperties.mModelName == mProperties.mFileName)
|
|
mProperties.mModelName = FileName;
|
|
mProperties.mFileName = FileName;
|
|
}
|
|
|
|
const QString& GetFileName() const
|
|
{
|
|
return mProperties.mFileName;
|
|
}
|
|
|
|
void SetDescription(const QString& Description)
|
|
{
|
|
mProperties.mDescription = Description;
|
|
}
|
|
|
|
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 InsertStepAction(lcStep Step);
|
|
void RemoveStepAction(lcStep Step);
|
|
|
|
template<typename StateType, typename ObjectType>
|
|
void LoadObjectHistoryState(const std::vector<StateType>& ObjectStates, std::vector<std::unique_ptr<ObjectType>>& Objects);
|
|
void LoadEditHistoryState(const lcModelHistoryEditState& HistoryState);
|
|
void LoadModelPropertiesState(const lcModelProperties& ModelProperties);
|
|
|
|
lcPiece* AddPiece(PieceInfo* Info, quint32 Section);
|
|
void AddPiece(std::unique_ptr<lcPiece> Piece, size_t PieceIndex);
|
|
void DeleteSelectedObjects();
|
|
void ResetSelectedPiecesPivotPoint();
|
|
void RemoveSelectedObjectsKeyFrames();
|
|
void InsertControlPoint();
|
|
void RemoveFocusedControlPoint();
|
|
void FocusNextTrainTrack();
|
|
void FocusPreviousTrainTrack();
|
|
void RotateFocusedTrainTrack(int Direction);
|
|
void ShowSelectedPiecesEarlier();
|
|
void ShowSelectedPiecesLater();
|
|
void InsertStepAndMoveSelectedPieces(lcStep Step);
|
|
void SetPieceSteps(const std::vector<std::pair<lcPiece*, lcStep>>& PieceSteps);
|
|
void RenamePiece(PieceInfo* Info);
|
|
|
|
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();
|
|
|
|
void SaveLDraw(QTextStream& Stream, bool SelectedOnly, lcStep LastStep) const;
|
|
void LoadLDraw(QIODevice& Device, Project* Project);
|
|
bool LoadBinary(lcFile* File);
|
|
bool LoadLDD(const QString& FileData);
|
|
bool LoadInventory(const QByteArray& Inventory);
|
|
int SplitMPD(QIODevice& Device);
|
|
void Merge(std::unique_ptr<lcModel> Other);
|
|
|
|
void SetMinifig(const lcMinifig& Minifig);
|
|
void SetPreviewPieceInfo(PieceInfo* Info, int ColorIndex);
|
|
|
|
void Cut();
|
|
void Copy();
|
|
void Paste(bool PasteToCurrentStep);
|
|
void DuplicateSelectedPieces();
|
|
void PaintSelectedPieces();
|
|
void UpdateTrainTrackConnections(lcPiece* TrackPiece, bool IgnoreSelected) const;
|
|
void UpdateSelectedPiecesTrainTrackConnections();
|
|
|
|
void GetScene(lcScene* Scene, const lcCamera* ViewCamera, bool AllowHighlight, bool AllowFade) const;
|
|
void AddSubModelRenderMeshes(lcScene* Scene, const lcMatrix44& WorldMatrix, int DefaultColorIndex, lcRenderMeshState RenderMeshState, bool ParentActive) const;
|
|
QImage GetStepImage(bool Zoom, int Width, int Height, lcStep Step);
|
|
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);
|
|
|
|
void RayTest(lcObjectRayTest& ObjectRayTest) const;
|
|
void BoxTest(lcObjectBoxTest& ObjectBoxTest) const;
|
|
bool SubModelMinIntersectDist(const lcVector3& WorldStart, const lcVector3& WorldEnd, float& MinDistance, lcPieceInfoRayTest& PieceInfoRayTest) const;
|
|
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;
|
|
|
|
bool HasPieces() const
|
|
{
|
|
return !mPieces.empty();
|
|
}
|
|
|
|
bool AnyPiecesSelected() const;
|
|
bool AnyObjectsSelected() const;
|
|
lcModel* GetFirstSelectedSubmodel() const;
|
|
void GetSubModels(std::set<lcModel*>& SubModels) const;
|
|
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
|
|
bool CanRotateSelection() const;
|
|
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
|
|
lcVector3 GetSelectionOrModelCenter() const;
|
|
bool GetFocusPosition(lcVector3& Position) const;
|
|
lcObject* GetFocusObject() const;
|
|
bool GetSelectionCenter(lcVector3& Center) const;
|
|
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;
|
|
void GetPartsListForStep(lcStep Step, int DefaultColorIndex, lcPartsList& PartsList, bool Cumulative) const;
|
|
void GetModelParts(const lcMatrix44& WorldMatrix, int DefaultColorIndex, std::vector<lcModelPartsEntry>& ModelParts) const;
|
|
void GetSelectionInformation(int* Flags, std::vector<lcObject*>& Selection, lcObject** Focus) const;
|
|
|
|
void ClearSelectionAction();
|
|
void SetSelectionAndFocusAction(const std::vector<lcObject*>& Selection, lcObject* Focus, quint32 Section, lcSelectionMode SelectionMode);
|
|
void FocusOrDeselectObjectAction(lcObject* Object, uint32_t Section, lcSelectionMode SelectionMode);
|
|
void SelectAllPiecesAction();
|
|
void InvertPieceSelectionAction();
|
|
void AddToSelectionAction(const std::vector<lcObject*>& Objects);
|
|
void RemoveFromSelectionAction(const std::vector<lcObject*>& Objects);
|
|
|
|
void HideSelectedPieces();
|
|
void HideUnselectedPieces();
|
|
void UnhideSelectedPieces();
|
|
void UnhideAllPieces();
|
|
|
|
void FindReplacePiece(bool SearchForward, bool FindAll, bool Replace);
|
|
|
|
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(lcTool Tool, lcView* View);
|
|
void EndMouseTool(lcTool Tool, lcView* View, bool Accept);
|
|
void InsertPieceToolClicked(const std::vector<lcInsertPieceInfo>& PieceInfoTransforms);
|
|
void InsertCameraToolClicked(const lcVector3& Position);
|
|
void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType);
|
|
void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag);
|
|
void UpdateFreeMoveTool(lcPiece* MousePiece, const lcMatrix44& StartTransform, const lcMatrix44& NewTransform, bool IsConnection, bool AlternateButtonDrag);
|
|
void UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag);
|
|
void UpdateScaleTool(const float Scale);
|
|
void EraserToolClicked(lcObject* Object);
|
|
void PaintToolClicked(lcObject* Object);
|
|
void ColorPickerToolClicked(const lcObject* Object);
|
|
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(lcView* View, 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);
|
|
void Zoom(lcCamera* Camera, float Amount);
|
|
|
|
void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Checkpoint, bool FirstMove, lcModelHistoryEditMerge ModelHistoryEditMerge)
|
|
{
|
|
MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Checkpoint, FirstMove, ModelHistoryEditMerge);
|
|
}
|
|
|
|
void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Checkpoint, bool FirstMove, lcModelHistoryEditMerge ModelHistoryEditMerge);
|
|
void RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Checkpoint, lcModelHistoryEditMerge ModelHistoryEditMerge);
|
|
void ScaleSelectedPieces(const float Scale);
|
|
void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform);
|
|
void SetObjectsKeyFrame(const std::vector<lcObject*>& Objects, lcObjectPropertyId PropertyId, bool KeyFrame);
|
|
void SetSelectedPiecesColorIndex(int ColorIndex);
|
|
void SetSelectedPiecesStepShow(lcStep Step);
|
|
void SetSelectedPiecesStepHide(lcStep Step);
|
|
|
|
void SetObjectsProperty(const std::vector<lcObject*>& Objects, lcObjectPropertyId PropertyId, QVariant Value);
|
|
void EndPropertyEdit(lcObjectPropertyId PropertyId, bool Accept);
|
|
|
|
void SetCameraProjection(lcCamera* Camera, lcCameraProjection CameraProjection);
|
|
|
|
void ShowPropertiesDialog();
|
|
void ShowArrayDialog();
|
|
void ShowMinifigDialog();
|
|
void UpdateInterface();
|
|
|
|
protected:
|
|
void DeleteModel();
|
|
|
|
void AddSelectionHistory(std::function<void()> Callback);
|
|
void ClearSelection();
|
|
void SetFocus(lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode);
|
|
void SetSelectionAndFocus(const std::vector<lcObject*>& Objects, lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode);
|
|
void SelectAllPieces();
|
|
void InvertPieceSelection();
|
|
void AddToSelection(const std::vector<lcObject*>& Objects);
|
|
void RemoveFromSelection(const std::vector<lcObject*>& Objects);
|
|
void BeginEditHistory(lcModelHistoryEditMerge ModelHistoryEditMerge);
|
|
void EndEditHistory();
|
|
void SetModelProperties(const lcModelProperties& ModelProperties);
|
|
|
|
void RunHistorySequence(const std::vector<std::unique_ptr<lcModelHistory>>& HistorySequence, bool Apply);
|
|
void BeginHistorySequence();
|
|
void EndHistorySequence(const QString& Description);
|
|
void DiscardHistorySequence();
|
|
void RevertHistorySequence();
|
|
void RemoveFirstUndoIfUnchanged();
|
|
const lcModelHistoryEntry* GetFirstUndoChange() const;
|
|
|
|
QString GetGroupName(const QString& Prefix);
|
|
void RemoveEmptyGroups();
|
|
bool RemoveSelectedObjects();
|
|
void RemoveCameraFromViews(lcCamera* Camera);
|
|
|
|
std::vector<lcObject*> GetSelectionModePieces(lcSelectionMode SelectionMode, const lcPiece* SelectedPiece) const;
|
|
void DeselectAllObjects();
|
|
void SetFocusedObject(lcObject* FocusObject, uint32_t FocusSection, lcSelectionMode SelectionMode);
|
|
void SetObjectsSelected(const std::vector<lcObject*>& Objects, bool Selected);
|
|
void SelectGroup(lcGroup* TopGroup, bool Select);
|
|
|
|
size_t AddPiece(lcPiece* Piece);
|
|
void InsertStep(lcStep Step);
|
|
|
|
lcPOVRayOptions mPOVRayOptions;
|
|
lcModelProperties mProperties;
|
|
Project* const mProject;
|
|
PieceInfo* mPieceInfo;
|
|
|
|
bool mIsPreview;
|
|
bool mActive;
|
|
lcStep mCurrentStep;
|
|
lcVector3 mMouseToolDistance;
|
|
bool mMouseToolFirstMove;
|
|
|
|
std::vector<std::unique_ptr<lcPiece>> mPieces;
|
|
std::vector<std::unique_ptr<lcCamera>> mCameras;
|
|
std::vector<std::unique_ptr<lcLight>> mLights;
|
|
std::vector<std::unique_ptr<lcGroup>> mGroups;
|
|
QStringList mFileLines;
|
|
|
|
std::vector<std::unique_ptr<lcModelHistory>> mHistorySequence;
|
|
const lcModelHistoryEntry* mSavedHistory = nullptr;
|
|
std::vector<std::unique_ptr<lcModelHistoryEntry>> mUndoHistory;
|
|
std::vector<std::unique_ptr<lcModelHistoryEntry>> mRedoHistory;
|
|
|
|
Q_DECLARE_TR_FUNCTIONS(lcModel);
|
|
};
|