From b6f7f92e7ecf511ab2dcb28cc5b2de0a482d3149 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Wed, 6 May 2026 20:59:46 -0700 Subject: [PATCH] Update all views during piece insert. Fixes #942. --- common/lc_model.cpp | 50 ++++++++++++++++++++++---- common/lc_model.h | 9 ++++- common/lc_view.cpp | 68 ++++++++++++++++++------------------ common/lc_view.h | 3 +- common/lc_viewwidget.cpp | 7 ++++ common/lc_viewwidget.h | 1 + qt/lc_qpreferencesdialog.cpp | 4 +++ 7 files changed, 98 insertions(+), 44 deletions(-) diff --git a/common/lc_model.cpp b/common/lc_model.cpp index f31b9f28..f8d44524 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -189,6 +189,16 @@ lcModel::lcModel(const QString& FileName, Project* Project, bool Preview) lcModel::~lcModel() { + if (!mPreviewInsertPieceInfo.empty()) + { + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + + for (lcInsertPieceInfo& PreviewPieceInfoTransform : mPreviewInsertPieceInfo) + Library->ReleasePieceInfo(PreviewPieceInfoTransform.Info); + + mPreviewInsertPieceInfo.clear(); + } + if (mPieceInfo) { if (!mIsPreview && gMainWindow && gMainWindow->GetCurrentPieceInfo() == mPieceInfo) @@ -2878,6 +2888,21 @@ void lcModel::UpdateSelectedPiecesTrainTrackConnections() } } +void lcModel::SetPreviewInsertPieceInfo(std::vector&& PreviewInsertPieceInfo) +{ + lcPiecesLibrary* Library = lcGetPiecesLibrary(); + + for (lcInsertPieceInfo& InfoTransform : PreviewInsertPieceInfo) + Library->LoadPieceInfo(InfoTransform.Info, true, true); + + for (lcInsertPieceInfo& PreviewPieceInfoTransform : mPreviewInsertPieceInfo) + Library->ReleasePieceInfo(PreviewPieceInfoTransform.Info); + + mPreviewInsertPieceInfo = std::move(PreviewInsertPieceInfo); + + UpdateAllViews(); +} + void lcModel::DeleteSelectedObjects() { if (mIsPreview) @@ -4940,27 +4965,36 @@ void lcModel::EndMouseTool(lcTool Tool, lcView* View, bool Accept) } } -void lcModel::InsertPieceToolClicked(const std::vector& PieceInfoTransforms) +bool lcModel::InsertPieceToolClicked(std::optional Transform) { - if (PieceInfoTransforms.empty()) - return; + if (mPreviewInsertPieceInfo.empty()) + return false; BeginHistorySequence(); BeginEditHistory(lcModelHistoryEditMerge::None); lcPiece* Piece = nullptr; - for (const lcInsertPieceInfo& PieceInfoTransform : PieceInfoTransforms) + for (const lcInsertPieceInfo& InsertPieceInfo : mPreviewInsertPieceInfo) { - Piece = new lcPiece(PieceInfoTransform.Info); + Piece = new lcPiece(InsertPieceInfo.Info); - Piece->Initialize(PieceInfoTransform.Transform, mCurrentStep); - Piece->SetColorIndex(PieceInfoTransform.ColorIndex); + lcMatrix44 PieceTransform; + + if (Transform.has_value()) + PieceTransform = lcMul(InsertPieceInfo.Transform, Transform.value()); + else + PieceTransform = InsertPieceInfo.Transform; + + Piece->Initialize(PieceTransform, mCurrentStep); + Piece->SetColorIndex(InsertPieceInfo.ColorIndex); Piece->UpdatePosition(mCurrentStep); AddPiece(Piece); } + SetPreviewInsertPieceInfo(std::vector()); + EndEditHistory(); SetSelectionAndFocus(std::vector(), Piece, LC_PIECE_SECTION_POSITION, lcSelectionMode::Single); @@ -4971,6 +5005,8 @@ void lcModel::InsertPieceToolClicked(const std::vector& Piece gMainWindow->UpdateInUseCategory(); UpdateTrainTrackConnections(Piece, false); + + return true; } void lcModel::InsertCameraToolClicked(const lcVector3& Position) diff --git a/common/lc_model.h b/common/lc_model.h index 587d6194..1c96f994 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -278,6 +278,12 @@ public: void PaintSelectedPieces(); void UpdateTrainTrackConnections(lcPiece* TrackPiece, bool IgnoreSelected) const; void UpdateSelectedPiecesTrainTrackConnections(); + void SetPreviewInsertPieceInfo(std::vector&& PreviewInsertPieceInfo); + + const std::vector& GetPreviewInsertPieceInfo() const + { + return mPreviewInsertPieceInfo; + } 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; @@ -345,7 +351,7 @@ public: void BeginMouseTool(lcTool Tool, lcView* View); void EndMouseTool(lcTool Tool, lcView* View, bool Accept); - void InsertPieceToolClicked(const std::vector& PieceInfoTransforms); + bool InsertPieceToolClicked(std::optional Transform); void InsertCameraToolClicked(const lcVector3& Position); void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType); void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag); @@ -436,6 +442,7 @@ protected: lcStep mCurrentStep; lcVector3 mMouseToolDistance; bool mMouseToolFirstMove; + std::vector mPreviewInsertPieceInfo; std::vector> mPieces; std::vector> mCameras; diff --git a/common/lc_view.cpp b/common/lc_view.cpp index 476d1e2f..ee626837 100644 --- a/common/lc_view.cpp +++ b/common/lc_view.cpp @@ -51,16 +51,6 @@ lcView::lcView(lcViewType ViewType, lcModel* Model) lcView::~lcView() { - if (!mPreviewInsertPieceInfo.empty()) - { - lcPiecesLibrary* Library = lcGetPiecesLibrary(); - - for (lcInsertPieceInfo& PreviewPieceInfoTransform : mPreviewInsertPieceInfo) - Library->ReleasePieceInfo(PreviewPieceInfoTransform.Info); - - mPreviewInsertPieceInfo.clear(); - } - mContext->DestroyVertexBuffer(mGridBuffer); if (gMainWindow && mViewType == lcViewType::View) @@ -497,15 +487,7 @@ void lcView::UpdatePiecePreview() } } - lcPiecesLibrary* Library = lcGetPiecesLibrary(); - - for (lcInsertPieceInfo& InfoTransform : InsertPieceInfo) - Library->LoadPieceInfo(InfoTransform.Info, true, true); - - for (lcInsertPieceInfo& PreviewPieceInfoTransform : mPreviewInsertPieceInfo) - Library->ReleasePieceInfo(PreviewPieceInfoTransform.Info); - - mPreviewInsertPieceInfo = std::move(InsertPieceInfo); + mModel->SetPreviewInsertPieceInfo(std::move(InsertPieceInfo)); } std::pair, bool> lcView::GetMouseInsertPieceInfo(bool IgnoreSelected, bool AllowNewPieces, PieceInfo* Info, lcPiece* MovingPiece) const @@ -898,11 +880,11 @@ void lcView::OnDraw() mModel->GetScene(mScene.get(), mCamera, Preferences.mHighlightNewParts, Preferences.mFadeSteps); - if (DrawInterface && mTrackTool == lcTrackTool::Insert) - { - UpdatePiecePreview(); + bool DrawInsertPreview = DrawInterface && std::any_of(mViews.begin(), mViews.end(), [](lcView* View){ return View->mTrackTool == lcTrackTool::Insert; }); - for (const lcInsertPieceInfo& PreviewPieceInfoTransform : mPreviewInsertPieceInfo) + if (DrawInsertPreview) + { + for (const lcInsertPieceInfo& PreviewPieceInfoTransform : mModel->GetPreviewInsertPieceInfo()) PreviewPieceInfoTransform.Info->AddRenderMeshes(mScene.get(), PreviewPieceInfoTransform.Transform, PreviewPieceInfoTransform.ColorIndex, lcRenderMeshState::Focused, false); } @@ -1473,10 +1455,11 @@ void lcView::DrawGrid() lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX); bool GridSizeValid = mModel->GetVisiblePiecesBoundingBox(Min, Max); + bool DrawInsertPreview = std::any_of(mViews.begin(), mViews.end(), [](lcView* View){ return View->mTrackTool == lcTrackTool::Insert; }); - if (mTrackTool == lcTrackTool::Insert) + if (DrawInsertPreview) { - for (const lcInsertPieceInfo& PreviewInsertPieceInfo : mPreviewInsertPieceInfo) + for (const lcInsertPieceInfo& PreviewInsertPieceInfo : mModel->GetPreviewInsertPieceInfo()) { lcVector3 Points[8]; lcGetBoxCorners(PreviewInsertPieceInfo.Info->GetBoundingBox(), Points); @@ -1748,10 +1731,8 @@ void lcView::EndDrag(bool Accept) break; case lcDragState::Piece: - { - if (!mPreviewInsertPieceInfo.empty()) - ActiveModel->InsertPieceToolClicked(mPreviewInsertPieceInfo); - } break; + ActiveModel->InsertPieceToolClicked(std::nullopt); + break; case lcDragState::Color: ActiveModel->PaintToolClicked(FindObjectUnderPointer(true, false).Object); @@ -1761,6 +1742,8 @@ void lcView::EndDrag(bool Accept) mDragState = lcDragState::None; UpdateTrackTool(); + + ActiveModel->SetPreviewInsertPieceInfo(std::vector()); ActiveModel->UpdateAllViews(); } @@ -2535,14 +2518,13 @@ void lcView::OnButtonDown(lcTrackButton TrackButton) { UpdatePiecePreview(); - if (mPreviewInsertPieceInfo.empty()) - break; + std::optional Transform; if (GetActiveModel() != mModel) - for (lcInsertPieceInfo& PreviewPieceInfoTransform : mPreviewInsertPieceInfo) - PreviewPieceInfoTransform.Transform = lcMul(PreviewPieceInfoTransform.Transform, lcMatrix44AffineInverse(mActiveSubmodelTransform)); + Transform = lcMatrix44AffineInverse(mActiveSubmodelTransform); - ActiveModel->InsertPieceToolClicked(mPreviewInsertPieceInfo); + if (!ActiveModel->InsertPieceToolClicked(Transform)) + break; if ((mMouseModifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(lcTool::Select); @@ -2859,7 +2841,10 @@ void lcView::OnMouseMove() UpdateTrackTool(); if (mTrackTool == lcTrackTool::Insert) + { + UpdatePiecePreview(); ActiveModel->UpdateAllViews(); + } return; } @@ -3159,6 +3144,21 @@ void lcView::OnMouseMove() } } +void lcView::OnMouseLeave() +{ + if (mTrackTool == lcTrackTool::Insert) + { + mTrackTool = lcTrackTool::None; + + UpdateCursor(); + + lcModel* ActiveModel = GetActiveModel(); + + if (ActiveModel) + ActiveModel->UpdateAllViews(); + } +} + void lcView::OnMouseWheel(float Direction) { float Scale = 10.0f; diff --git a/common/lc_view.h b/common/lc_view.h index 7ba63586..27255e9e 100644 --- a/common/lc_view.h +++ b/common/lc_view.h @@ -233,6 +233,7 @@ public: void OnForwardButtonDown(); void OnForwardButtonUp(); void OnMouseMove(); + void OnMouseLeave(); void OnMouseWheel(float Direction); void BeginDrag(lcDragState DragState); void EndDrag(bool Accept); @@ -358,8 +359,6 @@ protected: lcCamera* mCamera = nullptr; - std::vector mPreviewInsertPieceInfo; - lcVertexBuffer mGridBuffer; int mGridSettings[7]; diff --git a/common/lc_viewwidget.cpp b/common/lc_viewwidget.cpp index e313601d..2f562920 100644 --- a/common/lc_viewwidget.cpp +++ b/common/lc_viewwidget.cpp @@ -301,6 +301,13 @@ void lcViewWidget::wheelEvent(QWheelEvent* WheelEvent) WheelEvent->accept(); } +void lcViewWidget::leaveEvent(QEvent* Event) +{ + mView->OnMouseLeave(); + + QOpenGLWidget::leaveEvent(Event); +} + void lcViewWidget::dragEnterEvent(QDragEnterEvent* DragEnterEvent) { const QMimeData* MimeData = DragEnterEvent->mimeData(); diff --git a/common/lc_viewwidget.h b/common/lc_viewwidget.h index 856aecfe..56f7eb2d 100644 --- a/common/lc_viewwidget.h +++ b/common/lc_viewwidget.h @@ -38,6 +38,7 @@ protected: void mouseDoubleClickEvent(QMouseEvent* MouseEvent) override; void mouseMoveEvent(QMouseEvent* MouseEvent) override; void wheelEvent(QWheelEvent* WheelEvent) override; + void leaveEvent(QEvent* Event) override; void dragEnterEvent(QDragEnterEvent* DragEnterEvent) override; void dragLeaveEvent(QDragLeaveEvent* DragLeaveEvent) override; void dragMoveEvent(QDragMoveEvent* DragMoveEvent) override; diff --git a/qt/lc_qpreferencesdialog.cpp b/qt/lc_qpreferencesdialog.cpp index 18ac5749..b099a998 100644 --- a/qt/lc_qpreferencesdialog.cpp +++ b/qt/lc_qpreferencesdialog.cpp @@ -802,6 +802,10 @@ void lcPreferencesDialog::updateParts() void lcPreferencesDialog::CategoriesDropped(const QModelIndex& Parent, int First, int Last) { + Q_UNUSED(Parent); + Q_UNUSED(First); + Q_UNUSED(Last); + std::vector Categories; for (int Row = 0; Row < ui->categoriesTree->topLevelItemCount(); Row++)