mirror of
https://github.com/leozide/leocad
synced 2025-01-17 18:11:42 +01:00
Changed the LDraw exporter to include more features in extensions.
This commit is contained in:
parent
4c0c815682
commit
661fa68011
13 changed files with 975 additions and 142 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define LC_VERSION_TEXT "0.80.4"
|
||||
|
||||
// Forward declarations.
|
||||
class lcModel;
|
||||
class lcObject;
|
||||
class lcPiece;
|
||||
class lcCamera;
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -46,6 +46,10 @@ lcLight::~lcLight()
|
|||
{
|
||||
}
|
||||
|
||||
void lcLight::SaveLDraw(lcFile& File) const
|
||||
{
|
||||
}
|
||||
|
||||
QJsonObject lcLight::Save()
|
||||
{
|
||||
return QJsonObject();
|
||||
|
|
|
@ -170,6 +170,7 @@ public:
|
|||
return lcVector3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void SaveLDraw(lcFile& File) const;
|
||||
QJsonObject Save();
|
||||
void Load(QJsonObject Light);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
103
common/object.h
103
common/object.h
|
@ -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)
|
||||
|
|
176
common/piece.cpp
176
common/piece.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue