Changed the LDraw exporter to include more features in extensions.

This commit is contained in:
leo 2014-09-02 03:44:51 +00:00
parent 4c0c815682
commit 661fa68011
13 changed files with 975 additions and 142 deletions

View file

@ -78,6 +78,22 @@ void lcCamera::Initialize()
void lcCamera::CreateName(const lcArray<lcCamera*>& Cameras)
{
if (m_strName[0])
{
bool Found = false;
for (int CameraIdx = 0; CameraIdx < Cameras.GetSize(); CameraIdx++)
{
if (!strcmp(Cameras[CameraIdx]->m_strName, m_strName))
{
Found = true;
break;
}
}
if (!Found)
return;
}
int i, max = 0;
const char* Prefix = "Camera ";
@ -90,40 +106,168 @@ void lcCamera::CreateName(const lcArray<lcCamera*>& Cameras)
sprintf(m_strName, "%s %d", Prefix, max+1);
}
QJsonObject lcCamera::Save()
void lcCamera::SaveLDraw(lcFile& File) const
{
char Line[1024];
if (IsHidden())
{
strcpy(Line, "0 !LEOCAD CAMERA HIDDEN\r\n");
File.WriteBuffer(Line, strlen(Line));
}
if (IsOrtho())
{
strcpy(Line, "0 !LEOCAD CAMERA ORTHOGRAPHIC\r\n");
File.WriteBuffer(Line, strlen(Line));
}
sprintf(Line, "0 !LEOCAD CAMERA FOV %.2f\r\n", m_fovy);
File.WriteBuffer(Line, strlen(Line));
sprintf(Line, "0 !LEOCAD CAMERA ZNEAR %.2f\r\n", m_zNear);
File.WriteBuffer(Line, strlen(Line));
sprintf(Line, "0 !LEOCAD CAMERA ZFAR %.2f\r\n", m_zFar);
File.WriteBuffer(Line, strlen(Line));
if (mPositionKeys.GetSize() > 1)
SaveKeysLDraw(mPositionKeys, "CAMERA POSITION_KEY", File);
else
{
sprintf(Line, "0 !LEOCAD CAMERA POSITION %.2f %.2f %.2f\r\n", mPosition[0], mPosition[1], mPosition[2]);
File.WriteBuffer(Line, strlen(Line));
}
if (mTargetPositionKeys.GetSize() > 1)
SaveKeysLDraw(mTargetPositionKeys, "CAMERA TARGETPOSITION_KEY", File);
else
{
sprintf(Line, "0 !LEOCAD CAMERA TARGETPOSITION %.2f %.2f %.2f\r\n", mTargetPosition[0], mTargetPosition[1], mTargetPosition[2]);
File.WriteBuffer(Line, strlen(Line));
}
if (mUpVectorKeys.GetSize() > 1)
SaveKeysLDraw(mUpVectorKeys, "CAMERA UPVECTOR_KEY", File);
else
{
sprintf(Line, "0 !LEOCAD CAMERA UPVECTOR %.2f %.2f %.2f\r\n", mUpVector[0], mUpVector[1], mUpVector[2]);
File.WriteBuffer(Line, strlen(Line));
}
sprintf(Line, "0 !LEOCAD CAMERA NAME %s\r\n", m_strName);
File.WriteBuffer(Line, strlen(Line));
}
bool lcCamera::ParseLDrawLine(QString& Line)
{
QRegExp TokenExp("\\s*(\\w+)\\s+(.*)");
if (!Line.contains(TokenExp))
return false;
QString Token = TokenExp.cap(1);
Line = TokenExp.cap(2);
if (Token == QStringLiteral("HIDDEN"))
SetHidden(true);
else if (Token == QStringLiteral("ORTHOGRAPHIC"))
SetOrtho(true);
else if (Token == QStringLiteral("FOV"))
m_fovy = Line.toFloat();
else if (Token == QStringLiteral("ZNEAR"))
m_zNear = Line.toFloat();
else if (Token == QStringLiteral("ZFAR"))
m_zFar = Line.toFloat();
else if (Token == QStringLiteral("POSITION"))
QTextStream(&Line) >> mPosition[0] >> mPosition[1] >> mPosition[2];
else if (Token == QStringLiteral("TARGETPOSITION"))
QTextStream(&Line) >> mTargetPosition[0] >> mTargetPosition[1] >> mTargetPosition[2];
else if (Token == QStringLiteral("UPVECTOR"))
QTextStream(&Line) >> mUpVector[0] >> mUpVector[1] >> mUpVector[2];
else if (Token == QStringLiteral("POSITION_KEY"))
LoadKeyLDraw(mPositionKeys, Line);
else if (Token == QStringLiteral("TARGETPOSITION_KEY"))
LoadKeyLDraw(mTargetPositionKeys, Line);
else if (Token == QStringLiteral("UPVECTOR_KEY"))
LoadKeyLDraw(mUpVectorKeys, Line);
else if (Token == QStringLiteral("NAME"))
{
QByteArray NameUtf = Line.toUtf8(); // todo: replace with qstring
strncpy(m_strName, NameUtf.constData(), sizeof(m_strName));
m_strName[sizeof(m_strName) - 1] = 0;
return true;
}
return false;
}
QJsonObject lcCamera::SaveJson() const
{
QJsonObject Camera;
Camera[QStringLiteral("FOV")] = QString::number(m_fovy);
Camera[QStringLiteral("ZNear")] = QString::number(m_zNear);
Camera[QStringLiteral("ZFar")] = QString::number(m_zFar);
Camera[QStringLiteral("Name")] = QString::fromLatin1(m_strName); // todo: replace with qstring
Camera[QStringLiteral("FOV")] = m_fovy;
Camera[QStringLiteral("ZNear")] = m_zNear;
Camera[QStringLiteral("ZFar")] = m_zFar;
Camera[QStringLiteral("Name")] = QString::fromUtf8(m_strName); // todo: replace with qstring
if (IsHidden())
Camera[QStringLiteral("Hidden")] = QStringLiteral("true");
if (IsOrtho())
Camera[QStringLiteral("Orthographic")] = QStringLiteral("true");
if (mPositionKeys.GetSize() < 2)
Camera[QStringLiteral("Position")] = QStringLiteral("%1 %2 %3").arg(QString::number(mPosition[0]), QString::number(mPosition[1]), QString::number(mPosition[2]));
Camera[QStringLiteral("Position")] = QJsonArray() << mPosition[0] << mPosition[1] << mPosition[2];
else
Camera[QStringLiteral("PositionKeys")] = SaveKeys(mPositionKeys);
Camera[QStringLiteral("PositionKeys")] = SaveKeysJson(mPositionKeys);
if (mTargetPositionKeys.GetSize() < 2)
Camera[QStringLiteral("TargetPosition")] = QStringLiteral("%1 %2 %3").arg(QString::number(mTargetPosition[0]), QString::number(mTargetPosition[1]), QString::number(mTargetPosition[2]));
Camera[QStringLiteral("TargetPosition")] = QJsonArray() << mTargetPosition[0] << mTargetPosition[1] << mTargetPosition[2];
else
Camera[QStringLiteral("TargetPositionKeys")] = SaveKeys(mTargetPositionKeys);
Camera[QStringLiteral("TargetPositionKeys")] = SaveKeysJson(mTargetPositionKeys);
if (mUpVectorKeys.GetSize() < 2)
Camera[QStringLiteral("UpVector")] = QStringLiteral("%1 %2 %3").arg(QString::number(mUpVector[0]), QString::number(mUpVector[1]), QString::number(mUpVector[2]));
Camera[QStringLiteral("UpVector")] = QJsonArray() << mUpVector[0] << mUpVector[1] << mUpVector[2];
else
Camera[QStringLiteral("UpVectorKeys")] = SaveKeys(mUpVectorKeys);
Camera[QStringLiteral("UpVectorKeys")] = SaveKeysJson(mUpVectorKeys);
return Camera;
}
void lcCamera::Load(QJsonObject Camera)
bool lcCamera::LoadJson(const QJsonObject& Camera)
{
QJsonValue FOV = Camera.value(QStringLiteral("FOV"));
if (!FOV.isUndefined())
m_fovy = FOV.toDouble();
QJsonValue ZNear = Camera.value(QStringLiteral("ZNear"));
if (!ZNear.isUndefined())
m_zNear = ZNear.toDouble();
QJsonValue ZFar = Camera.value(QStringLiteral("ZFar"));
if (!ZFar.isUndefined())
m_zFar = ZFar.toDouble();
QJsonValue Name = Camera.value(QStringLiteral("Name"));
if (!Name.isUndefined())
{
QByteArray NameUtf = Name.toString().toUtf8(); // todo: replace with qstring
strncpy(m_strName, NameUtf.constData(), sizeof(m_strName));
m_strName[sizeof(m_strName) - 1] = 0;
}
QJsonValue Hidden = Camera.value(QStringLiteral("Hidden"));
if (!Hidden.isUndefined())
SetHidden(Hidden.toBool());
QJsonValue Ortho = Camera.value(QStringLiteral("Orthographic"));
if (!Ortho.isUndefined())
SetOrtho(Ortho.toBool());
LoadKeysJson(mPositionKeys, Camera.value(QStringLiteral("PositionKeys")), mPosition, Camera.value(QStringLiteral("Position")));
LoadKeysJson(mTargetPositionKeys, Camera.value(QStringLiteral("TargetPositionKeys")), mTargetPosition, Camera.value(QStringLiteral("TargetPosition")));
LoadKeysJson(mUpVectorKeys, Camera.value(QStringLiteral("UpVectorKeys")), mUpVector, Camera.value(QStringLiteral("UpVector")));
return true;
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -220,8 +220,11 @@ public:
return lcVector3(0.0f, 0.0f, 0.0f);
}
QJsonObject Save();
void Load(QJsonObject Camera);
void SaveLDraw(lcFile& File) const;
bool ParseLDrawLine(QString& Line);
QJsonObject SaveJson() const;
bool LoadJson(const QJsonObject& Camera);
@ -237,8 +240,19 @@ public:
{ return m_nType < LC_CAMERA_MAIN; }
bool IsVisible() const
{ return (mState & LC_CAMERA_HIDDEN) == 0; }
bool IsHidden() const
{ return (mState & LC_CAMERA_HIDDEN) != 0; }
{
return (mState & LC_CAMERA_HIDDEN) != 0;
}
void SetHidden(bool Hidden)
{
if (Hidden)
mState |= LC_CAMERA_HIDDEN;
else
mState &= ~LC_CAMERA_HIDDEN;
}
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
{

View file

@ -10,6 +10,7 @@
#define LC_VERSION_TEXT "0.80.4"
// Forward declarations.
class lcModel;
class lcObject;
class lcPiece;
class lcCamera;

View file

@ -3,8 +3,10 @@
#include "piece.h"
#include "camera.h"
#include "light.h"
#include "group.h"
#include "lc_mainwindow.h"
#include "lc_profile.h"
#include "lc_library.h"
void lcModelProperties::LoadDefaults()
{
@ -38,18 +40,177 @@ void lcModelProperties::SaveDefaults()
lcSetProfileInt(LC_PROFILE_DEFAULT_AMBIENT_COLOR, lcColorFromVector3(mAmbientColor));
}
QJsonObject lcModelProperties::Save()
void lcModelProperties::SaveLDraw(lcFile& File) const
{
char Line[1024];
if (!mName.IsEmpty())
{
sprintf(Line, "0 !LEOCAD MODEL NAME %s\r\n", mName);
File.WriteBuffer(Line, strlen(Line));
}
if (!mAuthor.IsEmpty())
{
sprintf(Line, "0 !LEOCAD MODEL AUTHOR %s\r\n", mAuthor);
File.WriteBuffer(Line, strlen(Line));
}
if (!mDescription.IsEmpty())
{
sprintf(Line, "0 !LEOCAD MODEL DESCRIPTION %s\r\n", mDescription);
File.WriteBuffer(Line, strlen(Line));
}
if (!mComments.IsEmpty())
{
sprintf(Line, "0 !LEOCAD MODEL COMMENTS %s\r\n", mComments);
File.WriteBuffer(Line, strlen(Line));
}
switch (mBackgroundType)
{
case LC_BACKGROUND_SOLID:
strcpy(Line, "0 !LEOCAD MODEL BACKGROUND_TYPE SOLID\r\n");
File.WriteBuffer(Line, strlen(Line));
break;
case LC_BACKGROUND_GRADIENT:
strcpy(Line, "0 !LEOCAD MODEL BACKGROUND_TYPE GRADIENT\r\n");
File.WriteBuffer(Line, strlen(Line));
break;
case LC_BACKGROUND_IMAGE:
strcpy(Line, "0 !LEOCAD MODEL BACKGROUND_TYPE IMAGE\r\n");
File.WriteBuffer(Line, strlen(Line));
break;
}
sprintf(Line, "0 !LEOCAD MODEL BACKGROUND SOLID_COLOR %.2f %.2f %.2f\r\n", mBackgroundSolidColor[0], mBackgroundSolidColor[1], mBackgroundSolidColor[2]);
File.WriteBuffer(Line, strlen(Line));
sprintf(Line, "0 !LEOCAD MODEL BACKGROUND GRADIENT_COLORS %.2f %.2f %.2f %.2f %.2f %.2f\r\n", mBackgroundGradientColor1[0], mBackgroundGradientColor1[1], mBackgroundGradientColor1[2], mBackgroundGradientColor2[0], mBackgroundGradientColor2[1], mBackgroundGradientColor2[2]);
File.WriteBuffer(Line, strlen(Line));
if (!mBackgroundImage.IsEmpty())
{
sprintf(Line, "0 !LEOCAD MODEL BACKGROUND IMAGE_NAME %s\r\n", mBackgroundImage);
File.WriteBuffer(Line, strlen(Line));
}
if (mBackgroundImageTile)
{
strcat(Line, "0 !LEOCAD MODEL BACKGROUND IMAGE_TILE\r\n");
File.WriteBuffer(Line, strlen(Line));
}
// bool mFogEnabled;
// float mFogDensity;
// lcVector3 mFogColor;
// lcVector3 mAmbientColor;
}
void lcModelProperties::ParseLDrawLine(char** Tokens)
{
if (!Tokens[4])
return;
strupr(Tokens[4]);
if (!strcmp(Tokens[4], "NAME"))
{
if (Tokens[5])
{
strncpy(mName, Tokens[5], sizeof(mName));
mName[sizeof(mName) - 1] = 0;
}
else
mName[0] = 0;
}
else if (!strcmp(Tokens[4], "AUTHOR"))
{
if (Tokens[5])
{
strncpy(mAuthor, Tokens[5], sizeof(mAuthor));
mAuthor[sizeof(mAuthor) - 1] = 0;
}
else
mAuthor[0] = 0;
}
else if (!strcmp(Tokens[4], "DESCRIPTION"))
{
if (Tokens[5])
{
strncpy(mDescription, Tokens[5], sizeof(mDescription));
mDescription[sizeof(mDescription) - 1] = 0;
}
else
mDescription[0] = 0;
}
else if (!strcmp(Tokens[4], "COMMENTS"))
{
if (Tokens[5])
{
strncpy(mComments, Tokens[5], sizeof(mComments));
mComments[sizeof(mComments) - 1] = 0;
}
else
mComments[0] = 0;
}
else if (!strcmp(Tokens[4], "BACKGROUND_TYPE"))
{
if (Tokens[5])
{
strupr(Tokens[5]);
if (!strcmp(Tokens[5], "SOLID"))
mBackgroundType = LC_BACKGROUND_SOLID;
else if (!strcmp(Tokens[5], "GRADIENT"))
mBackgroundType = LC_BACKGROUND_GRADIENT;
else if (!strcmp(Tokens[5], "IMAGE"))
mBackgroundType = LC_BACKGROUND_IMAGE;
}
}
else if (!strcmp(Tokens[4], "BACKGROUND"))
{
if (Tokens[5])
{
strupr(Tokens[5]);
}
}
/*
sprintf(Line, "0 !LEOCAD MODEL BACKGROUND SOLID_COLOR %.2f %.2f %.2f\r\n", mBackgroundSolidColor[0], mBackgroundSolidColor[1], mBackgroundSolidColor[2]);
File.WriteBuffer(Line, strlen(Line));
sprintf(Line, "0 !LEOCAD MODEL BACKGROUND GRADIENT_COLORS %.2f %.2f %.2f %.2f %.2f %.2f\r\n", mBackgroundGradientColor1[0], mBackgroundGradientColor1[1], mBackgroundGradientColor1[2], mBackgroundGradientColor2[0], mBackgroundGradientColor2[1], mBackgroundGradientColor2[2]);
File.WriteBuffer(Line, strlen(Line));
if (!mBackgroundImage.IsEmpty())
{
sprintf(Line, "0 !LEOCAD MODEL BACKGROUND IMAGE_NAME %s\r\n", mBackgroundImage);
File.WriteBuffer(Line, strlen(Line));
}
if (mBackgroundImageTile)
{
strcat(Line, "0 !LEOCAD MODEL BACKGROUND IMAGE_TILE\r\n");
File.WriteBuffer(Line, strlen(Line));
}
*/
}
QJsonObject lcModelProperties::Save() const
{
QJsonObject Properties;
if (!mName.IsEmpty())
Properties[QStringLiteral("Name")] = QString::fromLatin1(mName.Buffer());
Properties[QStringLiteral("Name")] = QString::fromLatin1(mName); // todo: qstring
if (!mAuthor.IsEmpty())
Properties[QStringLiteral("Author")] = QString::fromLatin1(mAuthor.Buffer());
Properties[QStringLiteral("Author")] = QString::fromLatin1(mAuthor);
if (!mDescription.IsEmpty())
Properties[QStringLiteral("Description")] = QString::fromLatin1(mDescription.Buffer());
Properties[QStringLiteral("Description")] = QString::fromLatin1(mDescription);
if (!mComments.IsEmpty())
Properties[QStringLiteral("Comments")] = QString::fromLatin1(mComments.Buffer());
Properties[QStringLiteral("Comments")] = QString::fromLatin1(mComments);
switch (mBackgroundType)
{
@ -68,7 +229,7 @@ QJsonObject lcModelProperties::Save()
Properties[QStringLiteral("BackgroundGradientColor1")] = QStringLiteral("%1 %2 %3").arg(QString::number(mBackgroundGradientColor1[0]), QString::number(mBackgroundGradientColor1[1]), QString::number(mBackgroundGradientColor1[2]));
Properties[QStringLiteral("BackgroundGradientColor2")] = QStringLiteral("%1 %2 %3").arg(QString::number(mBackgroundGradientColor2[0]), QString::number(mBackgroundGradientColor2[1]), QString::number(mBackgroundGradientColor2[2]));
if (!mBackgroundImage.IsEmpty())
Properties[QStringLiteral("BackgroundImage")] = QString::fromLatin1(mBackgroundImage.Buffer());
Properties[QStringLiteral("BackgroundImage")] = QString::fromLatin1(mBackgroundImage); // todo: qstring
if (mBackgroundImageTile)
Properties[QStringLiteral("BackgroundImageTile")] = QStringLiteral("true");
@ -81,8 +242,9 @@ QJsonObject lcModelProperties::Save()
return Properties;
}
void lcModelProperties::Load(QJsonObject Properties)
bool lcModelProperties::Load(const QJsonObject& Properties)
{
return true;
}
lcModel::lcModel()
@ -94,21 +256,208 @@ lcModel::~lcModel()
{
}
QJsonObject lcModel::Save()
void lcModel::SaveLDraw(lcFile& File) const
{
mProperties.SaveLDraw(File);
lcStep LastStep = GetLastStep();
if (mCurrentStep != LastStep)
{
char Line[1024];
sprintf(Line, "0 !LEOCAD MODEL CURRENT_STEP %d\r\n", mCurrentStep);
File.WriteBuffer(Line, strlen(Line));
}
for (lcStep Step = 1; Step <= LastStep; Step++)
{
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = mPieces[PieceIdx];
if (Piece->GetStepShow() == Step)
Piece->SaveLDraw(File);
}
if (Step != LastStep)
File.WriteBuffer("0 STEP\r\n", 8);
}
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
mCameras[CameraIdx]->SaveLDraw(File);
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
mLights[LightIdx]->SaveLDraw(File);
// lcArray<lcGroup*> mGroups;
}
void lcModel::LoadLDraw(const QStringList& Lines, const lcMatrix44& CurrentTransform, int DefaultColorCode, int& CurrentStep)
{
QRegExp TokenExp("\\s*(!?\\w+)\\s+(.*)");
lcPiece* Piece = NULL;
lcCamera* Camera = NULL;
lcLight* Light = NULL;
for (int LineIdx = 0; LineIdx < Lines.size(); LineIdx++)
{
QString Line = Lines[LineIdx].trimmed();
if (!Line.contains(TokenExp))
continue;
QString Token = TokenExp.cap(1);
Line = TokenExp.cap(2);
if (Token == QStringLiteral("0"))
{
if (!Line.contains(TokenExp))
continue;
Token = TokenExp.cap(1);
Line = TokenExp.cap(2);
if (Token == QStringLiteral("STEP"))
{
CurrentStep++;
continue;
}
if (Token != QStringLiteral("!LEOCAD"))
continue;
if (!Line.contains(TokenExp))
continue;
Token = TokenExp.cap(1);
Line = TokenExp.cap(2);
if (Token == QStringLiteral("MODEL"))
{
// if (!strcmp(Tokens[3], "CURRENT_STEP") && Tokens[4])
// mCurrentStep = atoi(Tokens[4]);
// mProperties.ParseLDrawLine(Tokens);
}
else if (Token == QStringLiteral("PIECE"))
{
if (!Piece)
Piece = new lcPiece(NULL);
Piece->ParseLDrawLine(Line, this);
}
else if (Token == QStringLiteral("CAMERA"))
{
if (!Camera)
Camera = new lcCamera(false);
if (Camera->ParseLDrawLine(Line))
{
Camera->CreateName(mCameras);
mCameras.Add(Camera);
Camera = NULL;
}
}
else if (Token == QStringLiteral("LIGHT"))
{
}
else if (Token == QStringLiteral("GROUP"))
{
}
continue;
}
else if (Token == QStringLiteral("1"))
{
QTextStream Stream(&Line, QIODevice::ReadOnly);
int ColorCode;
Stream >> ColorCode;
if (ColorCode == 16)
ColorCode = DefaultColorCode;
float Matrix[12];
for (int TokenIdx = 0; TokenIdx < 12; TokenIdx++)
Stream >> Matrix[TokenIdx];
lcMatrix44 IncludeTransform(lcVector4(Matrix[3], Matrix[6], Matrix[9], 0.0f), lcVector4(Matrix[4], Matrix[7], Matrix[10], 0.0f),
lcVector4(Matrix[5], Matrix[8], Matrix[11], 0.0f), lcVector4(Matrix[0], Matrix[1], Matrix[2], 1.0f));
IncludeTransform = lcMul(IncludeTransform, CurrentTransform);
QString File;
Stream >> File;
QString PartID = File.toUpper();
if (PartID.endsWith(QStringLiteral(".DAT")))
PartID = PartID.left(PartID.size() - 4);
if (!Piece)
Piece = new lcPiece(NULL);
PieceInfo* Info = lcGetPiecesLibrary()->FindPiece(PartID.toLatin1().constData(), false);
if (Info != NULL)
{
float* Matrix = IncludeTransform;
lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f),
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform);
AxisAngle[3] *= LC_RTOD;
Piece->SetPieceInfo(Info);
Piece->Initialize(lcVector3(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y), AxisAngle, CurrentStep);
Piece->SetColorCode(ColorCode);
Piece->CreateName(mPieces);
mPieces.Add(Piece);
Piece = NULL;
continue;
}
// todo: mpd
// todo: load from disk
Info = lcGetPiecesLibrary()->FindPiece(PartID.toLatin1().constData(), true);
if (Info != NULL)
{
float* Matrix = IncludeTransform;
lcMatrix44 Transform(lcVector4(Matrix[0], Matrix[2], -Matrix[1], 0.0f), lcVector4(Matrix[8], Matrix[10], -Matrix[9], 0.0f),
lcVector4(-Matrix[4], -Matrix[6], Matrix[5], 0.0f), lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
lcVector4 AxisAngle = lcMatrix44ToAxisAngle(Transform);
AxisAngle[3] *= LC_RTOD;
Piece->SetPieceInfo(Info);
Piece->Initialize(lcVector3(IncludeTransform[3].x, IncludeTransform[3].z, -IncludeTransform[3].y), AxisAngle, CurrentStep);
Piece->SetColorCode(ColorCode);
Piece->CreateName(mPieces);
mPieces.Add(Piece);
Piece = NULL;
continue;
}
}
}
delete Piece;
delete Camera;
delete Light;
}
QJsonObject lcModel::SaveJson() const
{
QJsonObject Model;
Model["Properties"] = mProperties.Save();
Model["CurrentStep"] = QString::number(mCurrentStep);
Model["CurrentStep"] = (int)mCurrentStep;
QJsonArray Pieces;
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
Pieces.append(mPieces[PieceIdx]->Save());
Pieces.append(mPieces[PieceIdx]->SaveJson());
Model["Pieces"] = Pieces;
QJsonArray Cameras;
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
Cameras.append(mCameras[CameraIdx]->Save());
Cameras.append(mCameras[CameraIdx]->SaveJson());
Model["Cameras"] = Cameras;
QJsonArray Lights;
@ -121,9 +470,114 @@ QJsonObject lcModel::Save()
return Model;
}
void lcModel::Load(QJsonObject Model)
bool lcModel::LoadJson(const QJsonObject& Model)
{
QJsonValue Properties = Model.value(QStringLiteral("Properties"));
if (!Properties.isUndefined())
mProperties.Load(Properties.toObject());
QJsonValue CurrentStep = Model.value(QStringLiteral("CurrentStep"));
if (!CurrentStep.isUndefined())
mCurrentStep = CurrentStep.toInt();
QJsonValue Pieces = Model.value(QStringLiteral("Pieces"));
if (!Pieces.isUndefined())
{
QJsonArray PiecesArray = Pieces.toArray();
for (int PieceIdx = 0; PieceIdx < PiecesArray.size(); PieceIdx++)
{
lcPiece* Piece = new lcPiece(NULL);
if (Piece->LoadJson(PiecesArray[PieceIdx].toObject()))
mPieces.Add(Piece);
else
delete Piece;
}
}
QJsonValue Cameras = Model.value(QStringLiteral("Cameras"));
if (!Cameras.isUndefined())
{
QJsonArray CamerasArray = Cameras.toArray();
for (int CameraIdx = 0; CameraIdx < CamerasArray.size(); CameraIdx++)
{
lcCamera* Camera = new lcCamera(false);
if (Camera->LoadJson(CamerasArray[CameraIdx].toObject()))
mCameras.Add(Camera);
else
delete Camera;
}
}
QJsonValue Lights = Model.value(QStringLiteral("Lights"));
if (!Lights.isUndefined())
{
QJsonArray LightsArray = Lights.toArray();
for (int LightIdx = 0; LightIdx < LightsArray.size(); LightIdx++)
{
/* lcLight* Light = new lcLight();
if (Light->Load(LightsArray[LightIdx].toObject()))
mLights.Add(Light);
else
delete Light;
*/ }
}
// groups
CalculateStep();
/*
if (!bMerge)
gMainWindow->UpdateFocusObject(GetFocusObject());
if (!bMerge)
{
for (int ViewIdx = 0; ViewIdx < Views.GetSize(); ViewIdx++)
{
View* view = Views[ViewIdx];
if (!view->mCamera->IsSimple())
view->SetDefaultCamera();
}
if (!bUndo)
ZoomExtents(0, Views.GetSize());
}
*/
gMainWindow->UpdateCameraMenu();
UpdateSelection();
gMainWindow->UpdateCurrentStep();
gMainWindow->UpdateAllViews();
return true;
}
void lcModel::CalculateStep()
{
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = mPieces[PieceIdx];
Piece->UpdatePosition(mCurrentStep);
if (Piece->IsSelected())
{
if (!Piece->IsVisible(mCurrentStep))
Piece->SetSelected(false);
else
SelectGroup(Piece->GetTopGroup(), true);
}
}
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
mCameras[CameraIdx]->UpdatePosition(mCurrentStep);
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
mLights[LightIdx]->UpdatePosition(mCurrentStep);
}
lcStep lcModel::GetLastStep() const
@ -136,6 +590,30 @@ lcStep lcModel::GetLastStep() const
return Step;
}
lcGroup* lcModel::GetGroup(const char* Name, bool CreateIfMissing)
{
for (int GroupIdx = 0; GroupIdx < mGroups.GetSize(); GroupIdx++)
{
lcGroup* Group = mGroups[GroupIdx];
if (!strcmp(Group->m_strName, Name))
return Group;
}
if (CreateIfMissing)
{
lcGroup* Group = new lcGroup();
mGroups.Add(Group);
strncpy(Group->m_strName, Name, sizeof(Group->m_strName));
Group->m_strName[sizeof(Group->m_strName) - 1] = 0;
return Group;
}
return NULL;
}
lcObject* lcModel::GetFocusObject() const
{
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)

View file

@ -54,8 +54,11 @@ public:
return true;
}
QJsonObject Save();
void Load(QJsonObject Properties);
void SaveLDraw(lcFile& File) const;
void ParseLDrawLine(char** Tokens);
QJsonObject Save() const;
bool Load(const QJsonObject& Properties);
String mName;
String mAuthor;
@ -95,7 +98,7 @@ enum lcTool
struct lcModelHistoryEntry
{
lcMemFile File;
QByteArray File;
char Description[64];
};
@ -137,8 +140,13 @@ public:
return mCurrentStep;
}
QJsonObject Save();
void Load(QJsonObject Model);
lcGroup* GetGroup(const char* Name, bool CreateIfMissing);
void SaveLDraw(lcFile& File) const;
void LoadLDraw(const QStringList& Lines, const lcMatrix44& CurrentTransform, int DefaultColorCode, int& CurrentStep);
QJsonObject SaveJson() const;
bool LoadJson(const QJsonObject& Model);
lcObject* GetFocusObject() const;
void FocusOrDeselectObject(const lcObjectSection& ObjectSection);
@ -148,6 +156,7 @@ public:
void AddToSelection(const lcArray<lcObjectSection>& ObjectSections);
protected:
void CalculateStep();
void UpdateSelection() const;
void SelectGroup(lcGroup* TopGroup, bool Select);
void ClearSelection(bool UpdateInterface);

View file

@ -46,6 +46,10 @@ lcLight::~lcLight()
{
}
void lcLight::SaveLDraw(lcFile& File) const
{
}
QJsonObject lcLight::Save()
{
return QJsonObject();

View file

@ -170,6 +170,7 @@ public:
return lcVector3(0.0f, 0.0f, 0.0f);
}
void SaveLDraw(lcFile& File) const;
QJsonObject Save();
void Load(QJsonObject Light);

View file

@ -1,5 +1,6 @@
#include "lc_global.h"
#include "object.h"
#include "lc_file.h"
lcObject::lcObject(lcObjectType ObjectType)
: mObjectType(ObjectType)
@ -10,36 +11,26 @@ lcObject::~lcObject()
{
}
QJsonArray lcObject::SaveKeys(const lcArray<lcObjectKey<lcVector3>>& Keys)
void lcObject::SaveKeysLDraw(const lcArray<lcObjectKey<lcVector3>>& Keys, const char* KeyName, lcFile& File) const
{
QJsonArray KeyArray;
char Line[1024];
for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++)
{
lcObjectKey<lcVector3>& Key = Keys[KeyIdx];
QJsonObject KeyObject;
KeyObject[QStringLiteral("Step")] = QString::number(Key.Step);
KeyObject[QStringLiteral("Value")] = QStringLiteral("%1 %2 %3").arg(QString::number(Key.Value[0]), QString::number(Key.Value[1]), QString::number(Key.Value[2]));
KeyArray.append(KeyObject);
sprintf(Line, "0 !LEOCAD %s %d %f %f %f\r\n", KeyName, Key.Step, Key.Value[0], Key.Value[1], Key.Value[2]);
File.WriteBuffer(Line, strlen(Line));
}
return KeyArray;
}
QJsonArray lcObject::SaveKeys(const lcArray<lcObjectKey<lcVector4>>& Keys)
void lcObject::SaveKeysLDraw(const lcArray<lcObjectKey<lcVector4>>& Keys, const char* KeyName, lcFile& File) const
{
QJsonArray KeyArray;
char Line[1024];
for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++)
{
lcObjectKey<lcVector4>& Key = Keys[KeyIdx];
QJsonObject KeyObject;
KeyObject[QStringLiteral("Step")] = QString::number(Key.Step);
KeyObject[QStringLiteral("Value")] = QStringLiteral("%1 %2 %3 %4").arg(QString::number(Key.Value[0]), QString::number(Key.Value[1]), QString::number(Key.Value[2]), QString::number(Key.Value[3]));
KeyArray.append(KeyObject);
sprintf(Line, "0 !LEOCAD %s %d %f %f %f %f\r\n", KeyName, Key.Step, Key.Value[0], Key.Value[1], Key.Value[2], Key.Value[3]);
File.WriteBuffer(Line, strlen(Line));
}
return KeyArray;
}

View file

@ -87,8 +87,107 @@ public:
virtual const char* GetName() const = 0;
protected:
QJsonArray SaveKeys(const lcArray<lcObjectKey<lcVector3>>& Keys);
QJsonArray SaveKeys(const lcArray<lcObjectKey<lcVector4>>& Keys);
void SaveKeysLDraw(const lcArray<lcObjectKey<lcVector3>>& Keys, const char* KeyName, lcFile& File) const;
void SaveKeysLDraw(const lcArray<lcObjectKey<lcVector4>>& Keys, const char* KeyName, lcFile& File) const;
template<typename T>
void LoadKeyLDraw(lcArray<lcObjectKey<T>>& Keys, QString& Line)
{
QRegExp TokenExp("\\s*(\\w+)\\s+(.*)");
if (!Line.contains(TokenExp))
return;
QString Token = TokenExp.cap(1);
Line = TokenExp.cap(2);
int Step = Token.toInt();
T Value;
QTextStream Stream(&Line);
const int Count = sizeof(T) / sizeof(float);
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Stream >> Value[ValueIdx];
lcObjectKey<T>& Key = Keys.Add();
Key.Step = Step;
Key.Value = Value;
}
template<typename T>
QJsonArray SaveKeysJson(const lcArray<lcObjectKey<T>>& Keys) const
{
const int Count = sizeof(T) / sizeof(float);
QJsonArray KeyArray;
QString StepString = QStringLiteral("Step");
QString ValueString = QStringLiteral("Value");
for (int KeyIdx = 0; KeyIdx < Keys.GetSize(); KeyIdx++)
{
lcObjectKey<T>& Key = Keys[KeyIdx];
QJsonArray ValueArray;
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
ValueArray << Key.Value[ValueIdx];
QJsonObject KeyObject;
KeyObject[StepString] = (int)Key.Step;
KeyObject[ValueString] = ValueArray;
KeyArray.append(KeyObject);
}
return KeyArray;
}
template<typename T>
void LoadKeysJson(lcArray<lcObjectKey<T>>& Keys, const QJsonValue& KeysValue, T& Single, const QJsonValue& SingleValue)
{
const int Count = sizeof(T) / sizeof(float);
Keys.SetSize(0);
QString StepString = QStringLiteral("Step");
QString ValueString = QStringLiteral("Value");
if (!KeysValue.isUndefined())
{
QJsonArray KeyArray = KeysValue.toArray();
Keys.AllocGrow(KeyArray.size());
for (int KeyIdx = 0; KeyIdx < KeyArray.size(); KeyIdx++)
{
QJsonObject KeyObject = KeyArray[KeyIdx].toObject();
QJsonValue Step = KeyObject.value(StepString);
QJsonValue Value = KeyObject.value(ValueString);
if (Step.isUndefined() || Value.isUndefined())
continue;
lcStep CurrentStep = Step.toInt();
if (!Keys.IsEmpty() && Keys[Keys.GetSize() - 1].Step >= CurrentStep)
continue;
lcObjectKey<T>& Key = Keys.Add();
Key.Step = CurrentStep;
QJsonArray ValueArray = Value.toArray();
if (ValueArray.size() == Count)
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Single[ValueIdx] = ValueArray[ValueIdx].toDouble();
}
}
else if (!SingleValue.isUndefined())
{
QJsonArray ValueArray = SingleValue.toArray();
if (ValueArray.size() == Count)
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
Single[ValueIdx] = ValueArray[ValueIdx].toDouble();
}
if (Keys.IsEmpty())
ChangeKey(Keys, Single, 1, true);
}
template<typename T>
const T& CalculateKey(const lcArray<lcObjectKey<T>>& Keys, lcStep Step)

View file

@ -23,8 +23,8 @@ lcPiece::lcPiece(PieceInfo* pPieceInfo)
{
mPieceInfo = pPieceInfo;
mState = 0;
mColorIndex = 0;
mColorCode = 0;
mColorIndex = gDefaultColor;
mColorCode = 16;
mStepShow = 1;
mStepHide = LC_STEP_MAX;
memset(m_strName, 0, sizeof(m_strName));
@ -43,35 +43,160 @@ lcPiece::~lcPiece()
mPieceInfo->Release();
}
QJsonObject lcPiece::Save()
void lcPiece::SaveLDraw(lcFile& File) const
{
char Line[1024];
if (mStepHide != LC_STEP_MAX)
{
sprintf(Line, "0 !LEOCAD PIECE STEP_HIDE %d\r\n", mStepHide);
File.WriteBuffer(Line, strlen(Line));
}
sprintf(Line, "0 !LEOCAD PIECE NAME %s\r\n", m_strName);
File.WriteBuffer(Line, strlen(Line));
if (IsHidden())
{
strcpy(Line, "0 !LEOCAD PIECE HIDDEN\r\n");
File.WriteBuffer(Line, strlen(Line));
}
if (mGroup)
{
sprintf(Line, "0 !LEOCAD PIECE GROUP %s\r\n", mGroup->m_strName);
File.WriteBuffer(Line, strlen(Line));
}
if (mPositionKeys.GetSize() > 1)
SaveKeysLDraw(mPositionKeys, "PIECE POSITION_KEY", File);
if (mRotationKeys.GetSize() > 1)
SaveKeysLDraw(mRotationKeys, "PIECE ROTATION_KEY", File);
const float* Matrix = mModelWorld;
float Numbers[12] = { Matrix[12], -Matrix[14], Matrix[13], Matrix[0], -Matrix[8], Matrix[4], -Matrix[2], Matrix[10], -Matrix[6], Matrix[1], -Matrix[9], Matrix[5] };
char Strings[12][32];
for (int NumberIdx = 0; NumberIdx < 12; NumberIdx++)
{
sprintf(Strings[NumberIdx], "%f", Numbers[NumberIdx]);
char* Dot = strchr(Strings[NumberIdx], '.');
if (Dot)
{
char* Last;
for (Last = Dot + strlen(Dot) - 1; *Last == '0'; Last--)
*Last = 0;
if (Last == Dot)
*Dot = 0;
}
}
sprintf(Line, "1 %d %s %s %s %s %s %s %s %s %s %s %s %s %s.DAT\r\n",
mColorCode, Strings[0], Strings[1], Strings[2], Strings[3], Strings[4], Strings[5], Strings[6], Strings[7], Strings[8], Strings[9], Strings[10], Strings[11], mPieceInfo->m_strName);
File.WriteBuffer(Line, strlen(Line));
}
bool lcPiece::ParseLDrawLine(QString& Line, lcModel* Model)
{
QRegExp TokenExp("\\s*(\\w+)\\s+(.*)");
if (!Line.contains(TokenExp))
return false;
QString Token = TokenExp.cap(1);
Line = TokenExp.cap(2);
if (Token == QStringLiteral("STEP_HIDE"))
mStepHide = Line.toInt();
else if (Token == QStringLiteral("NAME"))
{
QByteArray NameUtf = Line.toUtf8(); // todo: replace with qstring
strncpy(m_strName, NameUtf.constData(), sizeof(m_strName));
m_strName[sizeof(m_strName) - 1] = 0;
}
else if (Token == QStringLiteral("HIDDEN"))
SetHidden(true);
else if (Token == QStringLiteral("GROUP"))
mGroup = Model->GetGroup(Line.toUtf8(), true);
else if (Token == QStringLiteral("POSITION_KEY"))
LoadKeyLDraw(mPositionKeys, Line);
else if (Token == QStringLiteral("ROTATION_KEY"))
LoadKeyLDraw(mRotationKeys, Line);
return false;
}
QJsonObject lcPiece::SaveJson() const
{
QJsonObject Piece;
Piece[QStringLiteral("ID")] = QString::fromLatin1(mPieceInfo->m_strName);
Piece[QStringLiteral("Color")] = QString::number(mColorCode);
Piece[QStringLiteral("Step")] = QString::number(mStepShow);
Piece[QStringLiteral("Color")] = (int)mColorCode;
Piece[QStringLiteral("Step")] = (int)mStepShow;
if (mStepHide != LC_STEP_MAX)
Piece[QStringLiteral("StepHide")] = QString::number(mStepHide);
Piece[QStringLiteral("Name")] = QString::fromLatin1(m_strName); // todo: replace with qstring
Piece[QStringLiteral("StepHide")] = (int)mStepHide;
Piece[QStringLiteral("Name")] = QString::fromUtf8(m_strName); // todo: replace with qstring
if (IsHidden())
Piece[QStringLiteral("Hidden")] = QStringLiteral("true");
Piece[QStringLiteral("Hidden")] = true;
if (mPositionKeys.GetSize() < 2)
Piece[QStringLiteral("Position")] = QStringLiteral("%1 %2 %3").arg(QString::number(mPosition[0]), QString::number(mPosition[1]), QString::number(mPosition[2]));
Piece[QStringLiteral("Position")] = QJsonArray() << mPosition[0] << mPosition[1] << mPosition[2];
else
Piece[QStringLiteral("PositionKeys")] = SaveKeys(mPositionKeys);
Piece[QStringLiteral("PositionKeys")] = SaveKeysJson(mPositionKeys);
if (mRotationKeys.GetSize() < 2)
Piece[QStringLiteral("Rotation")] = QStringLiteral("%1 %2 %3 %4").arg(QString::number(mRotation[0]), QString::number(mRotation[1]), QString::number(mRotation[2]), QString::number(mRotation[3]));
Piece[QStringLiteral("Rotation")] = QJsonArray() << mRotation[0] << mRotation[1] << mRotation[2] << mRotation[3];
else
Piece[QStringLiteral("RotationKeys")] = SaveKeys(mRotationKeys);
Piece[QStringLiteral("RotationKeys")] = SaveKeysJson(mRotationKeys);
return Piece;
}
void lcPiece::Load(QJsonObject Piece)
bool lcPiece::LoadJson(const QJsonObject& Piece)
{
QJsonValue ID = Piece.value(QStringLiteral("ID"));
if (ID.isUndefined())
return false;
SetPieceInfo(lcGetPiecesLibrary()->FindPiece(ID.toString().toLatin1(), true));
QJsonValue Color = Piece.value(QStringLiteral("Color"));
if (!Color.isUndefined())
{
mColorCode = Color.toInt();
mColorIndex = lcGetColorIndex(mColorCode);
}
QJsonValue Step = Piece.value(QStringLiteral("Step"));
if (!Step.isUndefined())
mStepShow = Step.toInt();
QJsonValue StepHide = Piece.value(QStringLiteral("StepHide"));
if (!StepHide.isUndefined())
mStepHide = StepHide.toInt();
QJsonValue Name = Piece.value(QStringLiteral("Name"));
if (!Name.isUndefined())
{
QByteArray NameUtf = Name.toString().toUtf8(); // todo: replace with qstring
strncpy(m_strName, NameUtf.constData(), sizeof(m_strName));
m_strName[sizeof(m_strName) - 1] = 0;
}
QJsonValue Hidden = Piece.value(QStringLiteral("Hidden"));
if (!Hidden.isUndefined())
SetHidden(Hidden.toBool());
QJsonValue PositionKeys = Piece.value(QStringLiteral("PositionKeys"));
mPositionKeys.SetSize(0);
LoadKeysJson(mPositionKeys, Piece.value(QStringLiteral("PositionKeys")), mPosition, Piece.value(QStringLiteral("Position")));
LoadKeysJson(mRotationKeys, Piece.value(QStringLiteral("RotationKeys")), mRotation, Piece.value(QStringLiteral("Rotation")));
return true;
}
/////////////////////////////////////////////////////////////////////////////
@ -366,19 +491,38 @@ void lcPiece::Initialize(const lcVector3& Position, const lcVector4& AxisAngle,
void lcPiece::CreateName(const lcArray<lcPiece*>& Pieces)
{
if (m_strName[0])
{
bool Found = false;
for (int PieceIdx = 0; PieceIdx < Pieces.GetSize(); PieceIdx++)
{
if (!strcmp(Pieces[PieceIdx]->m_strName, m_strName))
{
Found = true;
break;
}
}
if (!Found)
return;
}
const char* Prefix = mPieceInfo->m_strDescription;
int Length = strlen(Prefix);
int i, max = 0;
for (int PieceIdx = 0; PieceIdx < Pieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = Pieces[PieceIdx];
if (strncmp(Piece->m_strName, mPieceInfo->m_strDescription, strlen(mPieceInfo->m_strDescription)) == 0)
if (sscanf(Piece->m_strName + strlen(mPieceInfo->m_strDescription), " #%d", &i) == 1)
if (strncmp(Piece->m_strName, Prefix, Length) == 0)
if (sscanf(Piece->m_strName + Length, " #%d", &i) == 1)
if (i > max)
max = i;
}
snprintf(m_strName, sizeof(m_strName), "%s #%.2d", mPieceInfo->m_strDescription, max+1);
snprintf(m_strName, sizeof(m_strName), "%s #%.2d", Prefix, max + 1);
m_strName[sizeof(m_strName) - 1] = 0;
}

View file

@ -88,8 +88,11 @@ public:
return lcVector3(0.0f, 0.0f, 0.0f);
}
QJsonObject Save();
void Load(QJsonObject Piece);
void SaveLDraw(lcFile& File) const;
bool ParseLDrawLine(QString& Line, lcModel* Model);
QJsonObject SaveJson() const;
bool LoadJson(const QJsonObject& Piece);
virtual void RayTest(lcObjectRayTest& ObjectRayTest) const;
virtual void BoxTest(lcObjectBoxTest& ObjectBoxTest) const;
@ -97,7 +100,7 @@ public:
void InsertTime(lcStep Start, lcStep Time);
void RemoveTime(lcStep Start, lcStep Time);
bool IsHidden()
bool IsHidden() const
{
return (mState & LC_PIECE_HIDDEN) != 0;
}

View file

@ -953,49 +953,8 @@ bool Project::DoSave(const char* FileName)
if ((strcmp(ext, "dat") == 0) || (strcmp(ext, "ldr") == 0))
{
char buf[256];
ptr = strrchr(m_strPathName, '\\');
if (ptr == NULL)
ptr = strrchr(m_strPathName, '/');
if (ptr == NULL)
ptr = m_strPathName;
else
ptr++;
sprintf(buf, "0 Model exported from LeoCAD\r\n0 Original name: %s\r\n", ptr);
if (!mProperties.mAuthor.IsEmpty())
{
strcat(buf, "0 Author: ");
strcat(buf, mProperties.mAuthor.Buffer());
strcat(buf, "\r\n");
}
strcat(buf, "\r\n");
file.WriteBuffer(buf, strlen(buf));
const char* OldLocale = setlocale(LC_NUMERIC, "C");
lcStep LastStep = GetLastStep();
for (lcStep Step = 1; Step <= LastStep; Step++)
{
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = mPieces[PieceIdx];
if ((Piece->IsVisible(Step)) && (Piece->GetStepShow() == Step))
{
const float* f = Piece->mModelWorld;
sprintf (buf, "1 %d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %s.DAT\r\n",
Piece->mColorCode, f[12], -f[14], f[13], f[0], -f[8], f[4], -f[2], f[10], -f[6], f[1], -f[9], f[5], Piece->mPieceInfo->m_strName);
file.WriteBuffer(buf, strlen(buf));
}
}
if (Step != LastStep)
file.WriteBuffer("0 STEP\r\n", 8);
}
file.WriteBuffer("0\r\n", 3);
SaveLDraw(file);
setlocale(LC_NUMERIC, OldLocale);
}
else
@ -1149,7 +1108,17 @@ bool Project::OnOpenDocument(const char* lpszPathName)
if (mpdfile)
FileReadLDraw(&FileArray[0]->File, mat, &ok, 16, &step, FileArray);
else
FileReadLDraw(&file, mat, &ok, 16, &step, FileArray);
// FileReadLDraw(&file, mat, &ok, 16, &step, FileArray);
{
QStringList Lines;
QFile File(lpszPathName);
if (!File.open(QIODevice::ReadOnly))
{
}
while (!File.atEnd())
Lines.append(File.readLine());
LoadLDraw(Lines, mat, 16, step);
}
mCurrentStep = step;
gMainWindow->UpdateCurrentStep();
@ -1211,7 +1180,7 @@ void Project::CheckPoint(const char* Description)
lcModelHistoryEntry* ModelHistoryEntry = new lcModelHistoryEntry();
strcpy(ModelHistoryEntry->Description, Description);
FileSave(&ModelHistoryEntry->File, true);
ModelHistoryEntry->File = QJsonDocument(SaveJson()).toBinaryData();
mUndoHistory.InsertAt(0, ModelHistoryEntry);
mRedoHistory.DeleteAll();
@ -1604,29 +1573,6 @@ bool Project::GetPiecesBoundingBox(View* view, float BoundingBox[6])
/////////////////////////////////////////////////////////////////////////////
// Project functions
void Project::CalculateStep()
{
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = mPieces[PieceIdx];
Piece->UpdatePosition(mCurrentStep);
if (Piece->IsSelected())
{
if (!Piece->IsVisible(mCurrentStep))
Piece->SetSelected(false);
else
SelectGroup(Piece->GetTopGroup(), true);
}
}
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
mCameras[CameraIdx]->UpdatePosition(mCurrentStep);
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
mLights[LightIdx]->UpdatePosition(mCurrentStep);
}
bool Project::RemoveSelectedObjects()
{
bool RemovedPiece = false;
@ -3526,7 +3472,7 @@ void Project::HandleCommand(LC_COMMANDS id)
mRedoHistory.InsertAt(0, Undo);
DeleteContents(true);
FileLoad(&mUndoHistory[0]->File, true, false);
LoadJson(QJsonDocument::fromBinaryData(mUndoHistory[0]->File).object());
gMainWindow->UpdateModified(IsModified());
gMainWindow->UpdateUndoRedo(mUndoHistory.GetSize() > 1 ? mUndoHistory[0]->Description : NULL, !mRedoHistory.IsEmpty() ? mRedoHistory[0]->Description : NULL);
@ -3543,7 +3489,7 @@ void Project::HandleCommand(LC_COMMANDS id)
mUndoHistory.InsertAt(0, Redo);
DeleteContents(true);
FileLoad(&Redo->File, true, false);
LoadJson(QJsonDocument::fromBinaryData(Redo->File).object());
gMainWindow->UpdateModified(IsModified());
gMainWindow->UpdateUndoRedo(mUndoHistory.GetSize() > 1 ? mUndoHistory[0]->Description : NULL, !mRedoHistory.IsEmpty() ? mRedoHistory[0]->Description : NULL);
@ -6067,7 +6013,7 @@ void Project::EndMouseTool(lcTool Tool, bool Accept)
if (!Accept)
{
DeleteContents(true);
FileLoad(&mUndoHistory[0]->File, true, false);
LoadJson(QJsonDocument::fromBinaryData(mUndoHistory[0]->File).object());
return;
}

View file

@ -190,7 +190,6 @@ protected:
bool RemoveSelectedObjects();
void GetPieceInsertPosition(lcPiece* OffsetPiece, lcVector3& Position, lcVector4& Rotation);
void CalculateStep();
static int InstanceOfName(const String& existingString, const String& candidateString, String& baseNameOut );
void FindPiece(bool FindFirst, bool SearchForward);