mirror of
https://github.com/leozide/leocad
synced 2025-01-14 08:01:45 +01:00
Merge pull request #874 from trevorsandy/BLENDER_AND_POVRAY_LIGHTS
Blender and POVRay Lights
This commit is contained in:
commit
0da3def563
42 changed files with 3533 additions and 1280 deletions
|
@ -142,20 +142,9 @@ void lcCamera::SaveLDraw(QTextStream& Stream) const
|
||||||
|
|
||||||
Stream << QLatin1String("0 !LEOCAD CAMERA FOV ") << m_fovy << QLatin1String(" ZNEAR ") << m_zNear << QLatin1String(" ZFAR ") << m_zFar << LineEnding;
|
Stream << QLatin1String("0 !LEOCAD CAMERA FOV ") << m_fovy << QLatin1String(" ZNEAR ") << m_zNear << QLatin1String(" ZFAR ") << m_zFar << LineEnding;
|
||||||
|
|
||||||
if (mPositionKeys.GetSize() > 1)
|
SaveAttribute(Stream, mPosition, mPositionKeys, "CAMERA", "POSITION");
|
||||||
mPositionKeys.SaveKeysLDraw(Stream, "CAMERA POSITION_KEY ");
|
SaveAttribute(Stream, mTargetPosition, mTargetPositionKeys, "CAMERA", "TARGET_POSITION");
|
||||||
else
|
SaveAttribute(Stream, mUpVector, mUpVectorKeys, "CAMERA", "UP_VECTOR");
|
||||||
Stream << QLatin1String("0 !LEOCAD CAMERA POSITION ") << mPosition[0] << ' ' << mPosition[1] << ' ' << mPosition[2] << LineEnding;
|
|
||||||
|
|
||||||
if (mTargetPositionKeys.GetSize() > 1)
|
|
||||||
mTargetPositionKeys.SaveKeysLDraw(Stream, "CAMERA TARGET_POSITION_KEY ");
|
|
||||||
else
|
|
||||||
Stream << QLatin1String("0 !LEOCAD CAMERA TARGET_POSITION ") << mTargetPosition[0] << ' ' << mTargetPosition[1] << ' ' << mTargetPosition[2] << LineEnding;
|
|
||||||
|
|
||||||
if (mUpVectorKeys.GetSize() > 1)
|
|
||||||
mUpVectorKeys.SaveKeysLDraw(Stream, "CAMERA UP_VECTOR_KEY ");
|
|
||||||
else
|
|
||||||
Stream << QLatin1String("0 !LEOCAD CAMERA UP_VECTOR ") << mUpVector[0] << ' ' << mUpVector[1] << ' ' << mUpVector[2] << LineEnding;
|
|
||||||
|
|
||||||
Stream << QLatin1String("0 !LEOCAD CAMERA ");
|
Stream << QLatin1String("0 !LEOCAD CAMERA ");
|
||||||
|
|
||||||
|
@ -176,7 +165,7 @@ bool lcCamera::ParseLDrawLine(QTextStream& Stream)
|
||||||
Stream >> Token;
|
Stream >> Token;
|
||||||
|
|
||||||
if (Token == QLatin1String("HIDDEN"))
|
if (Token == QLatin1String("HIDDEN"))
|
||||||
SetHidden(true);
|
SetHidden(true);
|
||||||
else if (Token == QLatin1String("ORTHOGRAPHIC"))
|
else if (Token == QLatin1String("ORTHOGRAPHIC"))
|
||||||
SetOrtho(true);
|
SetOrtho(true);
|
||||||
else if (Token == QLatin1String("FOV"))
|
else if (Token == QLatin1String("FOV"))
|
||||||
|
@ -185,27 +174,12 @@ bool lcCamera::ParseLDrawLine(QTextStream& Stream)
|
||||||
Stream >> m_zNear;
|
Stream >> m_zNear;
|
||||||
else if (Token == QLatin1String("ZFAR"))
|
else if (Token == QLatin1String("ZFAR"))
|
||||||
Stream >> m_zFar;
|
Stream >> m_zFar;
|
||||||
else if (Token == QLatin1String("POSITION"))
|
else if (LoadAttribute(Stream, Token, mPosition, mPositionKeys, "POSITION"))
|
||||||
{
|
continue;
|
||||||
Stream >> mPosition[0] >> mPosition[1] >> mPosition[2];
|
else if (LoadAttribute(Stream, Token, mTargetPosition, mTargetPositionKeys, "TARGET_POSITION"))
|
||||||
mPositionKeys.ChangeKey(mPosition, 1, true);
|
continue;
|
||||||
}
|
else if (LoadAttribute(Stream, Token, mUpVector, mUpVectorKeys, "UP_VECTOR"))
|
||||||
else if (Token == QLatin1String("TARGET_POSITION"))
|
continue;
|
||||||
{
|
|
||||||
Stream >> mTargetPosition[0] >> mTargetPosition[1] >> mTargetPosition[2];
|
|
||||||
mTargetPositionKeys.ChangeKey(mTargetPosition, 1, true);
|
|
||||||
}
|
|
||||||
else if (Token == QLatin1String("UP_VECTOR"))
|
|
||||||
{
|
|
||||||
Stream >> mUpVector[0] >> mUpVector[1] >> mUpVector[2];
|
|
||||||
mUpVectorKeys.ChangeKey(mUpVector, 1, true);
|
|
||||||
}
|
|
||||||
else if (Token == QLatin1String("POSITION_KEY"))
|
|
||||||
mPositionKeys.LoadKeysLDraw(Stream);
|
|
||||||
else if (Token == QLatin1String("TARGET_POSITION_KEY"))
|
|
||||||
mTargetPositionKeys.LoadKeysLDraw(Stream);
|
|
||||||
else if (Token == QLatin1String("UP_VECTOR_KEY"))
|
|
||||||
mUpVectorKeys.LoadKeysLDraw(Stream);
|
|
||||||
else if (Token == QLatin1String("NAME"))
|
else if (Token == QLatin1String("NAME"))
|
||||||
{
|
{
|
||||||
mName = Stream.readAll().trimmed();
|
mName = Stream.readAll().trimmed();
|
||||||
|
|
|
@ -202,7 +202,7 @@ public:
|
||||||
|
|
||||||
quint32 GetAllowedTransforms() const override
|
quint32 GetAllowedTransforms() const override
|
||||||
{
|
{
|
||||||
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcVector3 GetSectionPosition(quint32 Section) const override
|
lcVector3 GetSectionPosition(quint32 Section) const override
|
||||||
|
|
|
@ -123,7 +123,7 @@ lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mDefaultSettings [N
|
||||||
/* 2 LBL_BEVEL_EDGES */ {"beveledges", "1", QObject::tr("Bevel Edges"), QObject::tr("Adds a Bevel modifier for rounding off sharp edges")},
|
/* 2 LBL_BEVEL_EDGES */ {"beveledges", "1", QObject::tr("Bevel Edges"), QObject::tr("Adds a Bevel modifier for rounding off sharp edges")},
|
||||||
/* 3 LBL_BLENDFILE_TRUSTED */ {"blendfiletrusted", "0", QObject::tr("Trusted Blend File"), QObject::tr("Specify whether to treat the .blend file as being loaded from a trusted source")},
|
/* 3 LBL_BLENDFILE_TRUSTED */ {"blendfiletrusted", "0", QObject::tr("Trusted Blend File"), QObject::tr("Specify whether to treat the .blend file as being loaded from a trusted source")},
|
||||||
/* 4 LBL_CROP_IMAGE */ {"cropimage", "0", QObject::tr("Crop Image"), QObject::tr("Crop the image border at opaque content. Requires transparent background set to True")},
|
/* 4 LBL_CROP_IMAGE */ {"cropimage", "0", QObject::tr("Crop Image"), QObject::tr("Crop the image border at opaque content. Requires transparent background set to True")},
|
||||||
/* 5 LBL_CURVED_WALLS */ {"curvedwalls", "1", QObject::tr("Curved Walls"), QObject::tr("Makes surfaces look slightly concave")},
|
/* 5 LBL_CURVED_WALLS */ {"curvedwalls", "1", QObject::tr("Curved Walls"), QObject::tr("Makes surfaces look slightly concave, for interesting reflections")},
|
||||||
/* 6 LBL_FLATTEN_HIERARCHY */ {"flattenhierarchy", "0", QObject::tr("Flatten Hierarchy"), QObject::tr("In Scene Outline, all parts are placed directly below the root - there's no tree of submodels")},
|
/* 6 LBL_FLATTEN_HIERARCHY */ {"flattenhierarchy", "0", QObject::tr("Flatten Hierarchy"), QObject::tr("In Scene Outline, all parts are placed directly below the root - there's no tree of submodels")},
|
||||||
/* 7 LBL_IMPORT_CAMERAS */ {"importcameras", "1", QObject::tr("Import Cameras"), QObject::tr("%1 can specify camera definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
/* 7 LBL_IMPORT_CAMERAS */ {"importcameras", "1", QObject::tr("Import Cameras"), QObject::tr("%1 can specify camera definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
||||||
/* 8 LBL_IMPORT_LIGHTS */ {"importlights", "1", QObject::tr("Import Lights"), QObject::tr("%1 can specify point and sunlight definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
/* 8 LBL_IMPORT_LIGHTS */ {"importlights", "1", QObject::tr("Import Lights"), QObject::tr("%1 can specify point and sunlight definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
||||||
|
@ -147,12 +147,12 @@ lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mDefaultSettings [N
|
||||||
/*26 LBL_VERBOSE */ {"verbose", "1", QObject::tr("Verbose output"), QObject::tr("Output all messages while working, else only show warnings and errors")},
|
/*26 LBL_VERBOSE */ {"verbose", "1", QObject::tr("Verbose output"), QObject::tr("Output all messages while working, else only show warnings and errors")},
|
||||||
|
|
||||||
/*27/0 LBL_BEVEL_WIDTH */ {"bevelwidth", "0.5", QObject::tr("Bevel Width"), QObject::tr("Width of the bevelled edges")},
|
/*27/0 LBL_BEVEL_WIDTH */ {"bevelwidth", "0.5", QObject::tr("Bevel Width"), QObject::tr("Width of the bevelled edges")},
|
||||||
/*28/1 LBL_CAMERA_BORDER_PERCENT */ {"cameraborderpercentage", "5.0", QObject::tr("Camera Border Percent"), QObject::tr("When positioning the camera, include a (percentage) border around the model in the render")},
|
/*28/1 LBL_CAMERA_BORDER_PERCENT */ {"cameraborderpercentage", "5.0", QObject::tr("Camera Border Percent"), QObject::tr("When positioning the camera, include a (percentage) border leeway around the model in the rendered image")},
|
||||||
/*29/2 LBL_DEFAULT_COLOUR */ {"defaultcolour", "16", QObject::tr("Default Colour"), QObject::tr("Sets the default part colour using LDraw colour code")},
|
/*29/2 LBL_DEFAULT_COLOUR */ {"defaultcolour", "16", QObject::tr("Default Colour"), QObject::tr("Sets the default part colour using LDraw colour code")},
|
||||||
/*20/3 LBL_GAPS_SIZE */ {"gapwidth", "0.01", QObject::tr("Gap Width"), QObject::tr("Amount of gap space between each part")},
|
/*20/3 LBL_GAPS_SIZE */ {"realgapwidth", "0.0002", QObject::tr("Gap Width"), QObject::tr("Amount of space between each part (default 0.2mm)")},
|
||||||
/*31/4 LBL_IMAGE_WIDTH */ {"resolutionwidth", "800", QObject::tr("Image Width"), QObject::tr("Sets the rendered image width in pixels - from current step image, label shows config setting.")},
|
/*31/4 LBL_IMAGE_WIDTH */ {"resolutionwidth", "800", QObject::tr("Image Width"), QObject::tr("Sets the rendered image width in pixels - from current step image, label shows config setting.")},
|
||||||
/*32/5 LBL_IMAGE_HEIGHT */ {"resolutionheight", "600", QObject::tr("Image Height"), QObject::tr("Sets the rendered image height in pixels - from current step image, label shows config setting.")},
|
/*32/5 LBL_IMAGE_HEIGHT */ {"resolutionheight", "600", QObject::tr("Image Height"), QObject::tr("Sets the rendered image height in pixels - from current step image, label shows config setting.")},
|
||||||
/*33/6 LBL_IMAGE_SCALE */ {"scale", "0.02", QObject::tr("Image Scale"), QObject::tr("Sets the imported model scale (between .01 and 1.0). Scale is 1.0 and is huge and unwieldy in the viewport")},
|
/*33/6 LBL_IMAGE_SCALE */ {"realscale", "1.0", QObject::tr("Image Scale"), QObject::tr("Sets a scale for the model (1.0 = real life scale)")},
|
||||||
/*34/6 LBL_RENDER_PERCENTAGE */ {"renderpercentage", "100", QObject::tr("Render Percentage"), QObject::tr("Sets the rendered image percentage scale for its pixel resolution - updated from current step, label shows config setting.")},
|
/*34/6 LBL_RENDER_PERCENTAGE */ {"renderpercentage", "100", QObject::tr("Render Percentage"), QObject::tr("Sets the rendered image percentage scale for its pixel resolution - updated from current step, label shows config setting.")},
|
||||||
|
|
||||||
/*35/0 LBL_COLOUR_SCHEME */ {"usecolourscheme", "lgeo", QObject::tr("Colour Scheme"), QObject::tr("Colour scheme options - Realistic (lgeo), Original (LDConfig), Alternate (LDCfgalt), Custom (User Defined)")},
|
/*35/0 LBL_COLOUR_SCHEME */ {"usecolourscheme", "lgeo", QObject::tr("Colour Scheme"), QObject::tr("Colour scheme options - Realistic (lgeo), Original (LDConfig), Alternate (LDCfgalt), Custom (User Defined)")},
|
||||||
|
@ -183,29 +183,33 @@ lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mDefaultSettingsMM
|
||||||
/* 00 LBL_ADD_ENVIRONMENT_MM */ {"addenvironment", "1", QObject::tr("Add Environment"), QObject::tr("Adds a ground plane and environment texture")},
|
/* 00 LBL_ADD_ENVIRONMENT_MM */ {"addenvironment", "1", QObject::tr("Add Environment"), QObject::tr("Adds a ground plane and environment texture")},
|
||||||
/* 01 LBL_BEVEL_EDGES_MM */ {"beveledges", "0", QObject::tr("Bevel Edgest"), QObject::tr("Bevel edges. Can cause some parts to render incorrectly")},
|
/* 01 LBL_BEVEL_EDGES_MM */ {"beveledges", "0", QObject::tr("Bevel Edgest"), QObject::tr("Bevel edges. Can cause some parts to render incorrectly")},
|
||||||
/* 02 LBL_BLEND_FILE_TRUSTED_MM */ {"blendfiletrusted", "0", QObject::tr("Trusted Blend File"), QObject::tr("Specify whether to treat the .blend file as being loaded from a trusted source")},
|
/* 02 LBL_BLEND_FILE_TRUSTED_MM */ {"blendfiletrusted", "0", QObject::tr("Trusted Blend File"), QObject::tr("Specify whether to treat the .blend file as being loaded from a trusted source")},
|
||||||
/* 03 LBL_CROP_IMAGE_MM */ {"cropimage", "0", QObject::tr("Crop Image"), QObject::tr("Crop the image border at opaque content. Requires transparent background set to True")},
|
#ifdef Q_OS_LINUX
|
||||||
/* 04 LBL_DISPLAY_LOGO */ {"displaylogo", "1", QObject::tr("Display Logo"), QObject::tr("Display the logo on the stud")},
|
/* 03 LBL_CASE_SENSITIVE_FILESYSTEM */ {"casesensitivefilesystem", "1", QObject::tr("Case-sensitive Filesystem"),QObject::tr("Filesystem is case sensitive. Defaults to true on Linux.")},
|
||||||
/* 05 LBL_IMPORT_CAMERAS_MM */ {"importcameras", "1", QObject::tr("Import Cameras"), QObject::tr("%1 can specify camera definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
#else
|
||||||
/* 06 LBL_IMPORT_EDGES */ {"importedges", "0", QObject::tr("Import Edges"), QObject::tr("Import LDraw edges as edges")},
|
/* 03 LBL_CASE_SENSITIVE_FILESYSTEM */ {"casesensitivefilesystem", "0", QObject::tr("Case-sensitive Filesystem"),QObject::tr("Filesystem case sensitive defaults to false Windows and MacOS. Set true if LDraw path set to case-sensitive on case-insensitive filesystem.")},
|
||||||
/* 07 LBL_IMPORT_LIGHTS_MM */ {"importlights", "0", QObject::tr("Import Lights"), QObject::tr("%1 can specify point and sunlight definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
#endif
|
||||||
/* 08 LBL_KEEP_ASPECT_RATIO_MM */ {"keepaspectratio", "1", QObject::tr("Keep Aspect Ratio"), QObject::tr("Maintain the aspect ratio when resizing the output image - this attribute is not passed to Blender")},
|
/* 04 LBL_CROP_IMAGE_MM */ {"cropimage", "0", QObject::tr("Crop Image"), QObject::tr("Crop the image border at opaque content. Requires transparent background set to True")},
|
||||||
/* 09 LBL_MAKE_GAPS */ {"makegaps", "1", QObject::tr("Make Gaps"), QObject::tr("Make small gaps between bricks. A small gap is more realistic")},
|
/* 05 LBL_DISPLAY_LOGO */ {"displaylogo", "1", QObject::tr("Display Logo"), QObject::tr("Display the logo on the stud")},
|
||||||
/* 10 LBL_META_BFC */ {"metabfc", "1", QObject::tr("BFC"), QObject::tr("Process LDraw Back Face Culling meta commands")},
|
/* 06 LBL_IMPORT_CAMERAS_MM */ {"importcameras", "1", QObject::tr("Import Cameras"), QObject::tr("%1 can specify camera definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
||||||
/* 11 LBL_META_CLEAR */ {"metaclear", "0", QObject::tr("CLEAR Command"), QObject::tr("Hides all parts in the timeline up to where this command is encountered")},
|
/* 07 LBL_IMPORT_EDGES */ {"importedges", "0", QObject::tr("Import Edges"), QObject::tr("Import LDraw edges as edges")},
|
||||||
/* 12 LBL_META_GROUP */ {"metagroup", "1", QObject::tr("GROUP Command"), QObject::tr("Process GROUP meta commands")},
|
/* 08 LBL_IMPORT_LIGHTS_MM */ {"importlights", "1", QObject::tr("Import Lights"), QObject::tr("%1 can specify point and sunlight definitions within the ldraw data. Choose to load them or ignore them.").arg(LC_PRODUCTNAME_STR)},
|
||||||
/* 13 LBL_META_PAUSE */ {"metapause", "0", QObject::tr("PAUSE Command"), QObject::tr("Not implemented")},
|
/* 09 LBL_KEEP_ASPECT_RATIO_MM */ {"keepaspectratio", "1", QObject::tr("Keep Aspect Ratio"), QObject::tr("Maintain the aspect ratio when resizing the output image - this attribute is not passed to Blender")},
|
||||||
/* 14 LBL_META_PRINT_WRITE */ {"metaprintwrite", "0", QObject::tr("PRINT/WRITE Command"), QObject::tr("Prints PRINT/WRITE META commands to the system console.")},
|
/* 10 LBL_MAKE_GAPS */ {"makegaps", "1", QObject::tr("Make Gaps"), QObject::tr("Make small gaps between bricks. A small gap is more realistic")},
|
||||||
/* 15 LBL_META_SAVE */ {"metasave", "0", QObject::tr("SAVE Command"), QObject::tr("Not implemented")},
|
/* 11 LBL_META_BFC */ {"metabfc", "1", QObject::tr("BFC"), QObject::tr("Process LDraw Back Face Culling meta commands")},
|
||||||
/* 16 LBL_META_STEP */ {"metastep", "0", QObject::tr("STEP Command"), QObject::tr("Adds a keyframe that shows the part at the moment in the timeline")},
|
/* 12 LBL_META_CLEAR */ {"metaclear", "0", QObject::tr("CLEAR Command"), QObject::tr("Hides all parts in the timeline up to where this command is encountered")},
|
||||||
/* 17 LBL_META_STEP_GROUPS */ {"metastepgroups", "0", QObject::tr("STEP Groups"), QObject::tr("Create collection for individual steps")},
|
/* 13 LBL_META_GROUP */ {"metagroup", "1", QObject::tr("GROUP Command"), QObject::tr("Process GROUP meta commands")},
|
||||||
/* 18 LBL_META_TEXMAP */ {"metatexmap", "1", QObject::tr("TEXMAP and DATA Command"), QObject::tr("Process TEXMAP and DATA meta commands")},
|
/* 14 LBL_META_PAUSE */ {"metapause", "0", QObject::tr("PAUSE Command"), QObject::tr("Not implemented")},
|
||||||
/* 19 LBL_NO_STUDS */ {"nostuds", "0", QObject::tr("No Studs"), QObject::tr("Don't import studs")},
|
/* 15 LBL_META_PRINT_WRITE */ {"metaprintwrite", "0", QObject::tr("PRINT/WRITE Command"), QObject::tr("Prints PRINT/WRITE META commands to the system console.")},
|
||||||
/* 20 LBL_OVERWRITE_IMAGE_MM */ {"overwriteimage", "1", QObject::tr("Overwrite Image"), QObject::tr("Specify whether to overwrite an existing rendered image file")},
|
/* 16 LBL_META_SAVE */ {"metasave", "0", QObject::tr("SAVE Command"), QObject::tr("Not implemented")},
|
||||||
/* 21 LBL_POSITION_CAMERA_MM */ {"positioncamera", "1", QObject::tr("Position Camera"), QObject::tr("Position the camera to show the whole model")},
|
/* 17 LBL_META_STEP */ {"metastep", "0", QObject::tr("STEP Command"), QObject::tr("Adds a keyframe that shows the part at the moment in the timeline")},
|
||||||
/* 22 LBL_PARENT_TO_EMPTY */ {"parenttoempty", "1", QObject::tr("Parent To Empty"), QObject::tr("Parent the model to an empty")},
|
/* 18 LBL_META_STEP_GROUPS */ {"metastepgroups", "0", QObject::tr("STEP Groups"), QObject::tr("Create collection for individual steps")},
|
||||||
/* 23 LBL_PREFER_STUDIO */ {"preferstudio", "0", QObject::tr("Prefer Stud.io Library"), QObject::tr("Search for parts in Stud.io library first")},
|
/* 19 LBL_META_TEXMAP */ {"metatexmap", "1", QObject::tr("TEXMAP and DATA Command"), QObject::tr("Process TEXMAP and DATA meta commands")},
|
||||||
/* 24 LBL_PREFER_UNOFFICIAL */ {"preferunofficial", "0", QObject::tr("Prefer Unofficial Parts"), QObject::tr("Search for unofficial parts first")},
|
/* 20 LBL_NO_STUDS */ {"nostuds", "0", QObject::tr("No Studs"), QObject::tr("Don't import studs")},
|
||||||
/* 25 LBL_PRESERVE_HIERARCHY */ {"preservehierarchy", "0", QObject::tr("Preserve File Structure"), QObject::tr("Don't merge the constituent subparts and primitives into the top level part. Some parts may not render properly")},
|
/* 21 LBL_OVERWRITE_IMAGE_MM */ {"overwriteimage", "1", QObject::tr("Overwrite Image"), QObject::tr("Specify whether to overwrite an existing rendered image file")},
|
||||||
|
/* 22 LBL_POSITION_CAMERA_MM */ {"positioncamera", "1", QObject::tr("Position Camera"), QObject::tr("Position the camera to show the whole model")},
|
||||||
|
/* 23 LBL_PARENT_TO_EMPTY */ {"parenttoempty", "1", QObject::tr("Parent To Empty"), QObject::tr("Parent the model to an empty")},
|
||||||
|
/* 24 LBL_PREFER_STUDIO */ {"preferstudio", "0", QObject::tr("Prefer Stud.io Library"), QObject::tr("Search for parts in Stud.io library first")},
|
||||||
|
/* 25 LBL_PREFER_UNOFFICIAL */ {"preferunofficial", "0", QObject::tr("Prefer Unofficial Parts"), QObject::tr("Search for unofficial parts first")},
|
||||||
/* 26 LBL_PROFILE */ {"profile", "0", QObject::tr("Profile"), QObject::tr("Profile import performance")},
|
/* 26 LBL_PROFILE */ {"profile", "0", QObject::tr("Profile"), QObject::tr("Profile import performance")},
|
||||||
/* 27 LBL_RECALCULATE_NORMALS */ {"recalculatenormals", "0", QObject::tr("Recalculate Normals"), QObject::tr("Recalculate normals. Not recommended if BFC processing is active")},
|
/* 27 LBL_RECALCULATE_NORMALS */ {"recalculatenormals", "0", QObject::tr("Recalculate Normals"), QObject::tr("Recalculate normals. Not recommended if BFC processing is active")},
|
||||||
/* 28 LBL_REMOVE_DOUBLES_MM */ {"removedoubles", "1", QObject::tr("No Duplicate Vertices"), QObject::tr("Merge vertices that are within a certain distance.")},
|
/* 28 LBL_REMOVE_DOUBLES_MM */ {"removedoubles", "1", QObject::tr("No Duplicate Vertices"), QObject::tr("Merge vertices that are within a certain distance.")},
|
||||||
|
@ -215,43 +219,40 @@ lcBlenderPreferences::BlenderSettings lcBlenderPreferences::mDefaultSettingsMM
|
||||||
/* 32 LBL_SET_TIMELINE_MARKERS */ {"settimelinemarkers", "0", QObject::tr("Set Timeline Markers"), QObject::tr("Set timeline markers for meta commands")},
|
/* 32 LBL_SET_TIMELINE_MARKERS */ {"settimelinemarkers", "0", QObject::tr("Set Timeline Markers"), QObject::tr("Set timeline markers for meta commands")},
|
||||||
/* 33 LBL_SHADE_SMOOTH */ {"shadesmooth", "1", QObject::tr("Shade Smooth"), QObject::tr("Use flat or smooth shading for part faces")},
|
/* 33 LBL_SHADE_SMOOTH */ {"shadesmooth", "1", QObject::tr("Shade Smooth"), QObject::tr("Use flat or smooth shading for part faces")},
|
||||||
/* 34 LBL_TRANSPARENT_BACKGROUND_MM */ {"transparentbackground", "0", QObject::tr("Transparent Background"), QObject::tr("Specify whether to render a background")},
|
/* 34 LBL_TRANSPARENT_BACKGROUND_MM */ {"transparentbackground", "0", QObject::tr("Transparent Background"), QObject::tr("Specify whether to render a background")},
|
||||||
/* 35 LBL_TREAT_MODELS_WITH_SUBPARTS_AS_PARTS */ {"treatmodelswithsubpartsasparts","1", QObject::tr("Treat Subparts As Parts"), QObject::tr("Treat subpart like a part by merging its constituent parts into one object")},
|
/* 35 LBL_TREAT_SHORTCUT_AS_MODEL */ {"treatshortcutasmodel", "0", QObject::tr("Treat Shortcuts As Models"),QObject::tr("Split shortcut parts into their constituent pieces as if they were models")},
|
||||||
/* 36 LBL_TREAT_SHORTCUT_AS_MODEL */ {"treatshortcutasmodel", "0", QObject::tr("Treat Shortcuts As Models"),QObject::tr("Split shortcut parts into their constituent pieces as if they were models")},
|
/* 36 LBL_TRIANGULATE */ {"triangulate", "0", QObject::tr("Triangulate Faces"), QObject::tr("Triangulate all faces")},
|
||||||
/* 37 LBL_TRIANGULATE */ {"triangulate", "0", QObject::tr("Triangulate Faces"), QObject::tr("Triangulate all faces")},
|
/* 37 LBL_USE_ARCHIVE_LIBRARY_MM */ {"usearchivelibrary", "0", QObject::tr("Use Archive Libraries"), QObject::tr("Add any archive (zip) libraries in the LDraw file path to the library search list")},
|
||||||
/* 38 LBL_USE_ARCHIVE_LIBRARY_MM */ {"usearchivelibrary", "0", QObject::tr("Use Archive Libraries"), QObject::tr("Add any archive (zip) libraries in the LDraw file path to the library search list")},
|
/* 38 LBL_USE_FREESTYLE_EDGES */ {"usefreestyleedges", "0", QObject::tr("Use Freestyle Edges"), QObject::tr("Render LDraw edges using freestyle")},
|
||||||
/* 39 LBL_USE_FREESTYLE_EDGES */ {"usefreestyleedges", "0", QObject::tr("Use Freestyle Edges"), QObject::tr("Render LDraw edges using freestyle")},
|
/* 39 LBL_VERBOSE_MM */ {"verbose", "1", QObject::tr("Verbose output"), QObject::tr("Output all messages while working, else only show warnings and errors")},
|
||||||
/* 40 LBL_VERBOSE_MM */ {"verbose", "1", QObject::tr("Verbose output"), QObject::tr("Output all messages while working, else only show warnings and errors")},
|
|
||||||
|
|
||||||
/* 41/00 LBL_BEVEL_SEGMENTS */ {"bevelsegments", "4", QObject::tr("Bevel Segments"), QObject::tr("Bevel segments")},
|
/* 40/00 LBL_BEVEL_SEGMENTS */ {"bevelsegments", "4", QObject::tr("Bevel Segments"), QObject::tr("Bevel segments")},
|
||||||
/* 42/01 LBL_BEVEL_WEIGHT */ {"bevelweight", "0.3", QObject::tr("Bevel Weight"), QObject::tr("Bevel weight")},
|
/* 41/01 LBL_BEVEL_WEIGHT */ {"bevelweight", "0.3", QObject::tr("Bevel Weight"), QObject::tr("Bevel weight")},
|
||||||
/* 43/02 LBL_BEVEL_WIDTH_MM */ {"bevelwidth", "0.3", QObject::tr("Bevel Width"), QObject::tr("Width of the bevelled edges")},
|
/* 42/02 LBL_BEVEL_WIDTH_MM */ {"bevelwidth", "0.3", QObject::tr("Bevel Width"), QObject::tr("Width of the bevelled edges")},
|
||||||
/* 44/03 LBL_CAMERA_BORDER_PERCENT_MM */ {"cameraborderpercent", "5", QObject::tr("Camera Border Percent"), QObject::tr("When positioning the camera, include a (percentage) border around the model in the render")},
|
/* 43/03 LBL_CAMERA_BORDER_PERCENT_MM */ {"cameraborderpercent", "5", QObject::tr("Camera Border Percent"), QObject::tr("When positioning the camera, include a (percentage) border around the model in the render")},
|
||||||
/* 45/04 LBL_FRAMES_PER_STEP */ {"framesperstep", "3", QObject::tr("Frames Per Step"), QObject::tr("Frames per step")},
|
/* 44/04 LBL_FRAMES_PER_STEP */ {"framesperstep", "3", QObject::tr("Frames Per Step"), QObject::tr("Frames per step")},
|
||||||
/* 46/05 LBL_GAP_SCALE */ {"gapscale", "0.997", QObject::tr("Gap Scale"), QObject::tr("Scale individual parts by this much to create the gap")},
|
/* 45/05 LBL_GAP_SCALE */ {"gapscale", "0.997", QObject::tr("Gap Scale"), QObject::tr("Scale individual parts by this much to create the gap")},
|
||||||
/* 47/06 LBL_IMPORT_SCALE */ {"importscale", "0.02", QObject::tr("Import Scale"), QObject::tr("What scale to import at. Full scale is 1.0 and is so huge that it is unwieldy in the viewport")},
|
/* 46/06 LBL_IMPORT_SCALE */ {"importscale", "0.02", QObject::tr("Import Scale"), QObject::tr("What scale to import at. Full scale is 1.0 and is so huge that it is unwieldy in the viewport")},
|
||||||
/* 48/07 LBL_MERGE_DISTANCE */ {"mergedistance", "0.05", QObject::tr("Merge Distance"), QObject::tr("Maximum distance between elements to merge")},
|
/* 47/07 LBL_MERGE_DISTANCE */ {"mergedistance", "0.05", QObject::tr("Merge Distance"), QObject::tr("Maximum distance between elements to merge")},
|
||||||
/* 49/08 LBL_RENDER_PERCENTAGE_MM */ {"renderpercentage", "100", QObject::tr("Render Percentage"), QObject::tr("Sets the rendered image percentage scale for its pixel resolution - updated from current step, label shows config setting.")},
|
/* 48/08 LBL_RENDER_PERCENTAGE_MM */ {"renderpercentage", "100", QObject::tr("Render Percentage"), QObject::tr("Sets the rendered image percentage scale for its pixel resolution - updated from current step, label shows config setting.")},
|
||||||
/* 50/09 LBL_RESOLUTION_WIDTH */ {"resolutionwidth", "800", QObject::tr("Image Width"), QObject::tr("Sets the rendered image width in pixels - from current step image, label shows config setting.")},
|
/* 49/09 LBL_RESOLUTION_WIDTH */ {"resolutionwidth", "800", QObject::tr("Image Width"), QObject::tr("Sets the rendered image width in pixels - from current step image, label shows config setting.")},
|
||||||
/* 51/10 LBL_RESOLUTION_HEIGHT */ {"resolutionheight", "600", QObject::tr("Image Height"), QObject::tr("Sets the rendered image height in pixels - from current step image, label shows config setting.")},
|
/* 50/10 LBL_RESOLUTION_HEIGHT */ {"resolutionheight", "600", QObject::tr("Image Height"), QObject::tr("Sets the rendered image height in pixels - from current step image, label shows config setting.")},
|
||||||
/* 52/11 LBL_STARTING_STEP_FRAME */ {"startingstepframe", "1", QObject::tr("Starting Step Frame"), QObject::tr("Frame to add the first STEP meta command")},
|
/* 51/11 LBL_STARTING_STEP_FRAME */ {"startingstepframe", "1", QObject::tr("Starting Step Frame"), QObject::tr("Frame to add the first STEP meta command")},
|
||||||
|
|
||||||
/* 53/00 LBL_CHOSEN_LOGO */ {"chosenlogo", "logo3", QObject::tr("Chosen Logo"), QObject::tr("Which logo to display. logo and logo2 aren't used and are only included for completeness")},
|
/* 52/00 LBL_CHOSEN_LOGO */ {"chosenlogo", "logo3", QObject::tr("Chosen Logo"), QObject::tr("Which logo to display. logo and logo2 aren't used and are only included for completeness")},
|
||||||
/* 54/01 LBL_COLOUR_SCHEME_MM */ {"usecolourscheme", "lgeo", QObject::tr("Colour Scheme"), QObject::tr("Colour scheme options - Realistic (lgeo), Original (LDConfig), Alternate (LDCfgalt), Custom (User Defined)")},
|
/* 53/01 LBL_COLOUR_SCHEME_MM */ {"usecolourscheme", "lgeo", QObject::tr("Colour Scheme"), QObject::tr("Colour scheme options - Realistic (lgeo), Original (LDConfig), Alternate (LDCfgalt), Custom (User Defined)")},
|
||||||
/* 55/02 LBL_GAP_SCALE_STRATEGY */ {"gapscalestrategy", "constraint", QObject::tr("Gap Strategy"), QObject::tr("Apply gap to object directly or scale and empty to adjust to gaps between parts")},
|
/* 54/02 LBL_COLOUR_STRATEGY */ {"colorstrategy", "material", QObject::tr("How To Color Parts"), QObject::tr("Colour strategy options - Material (Default - use if exporting), Vertex colors (slightly quicker to import)")},
|
||||||
/* 56/03 LBL_GAP_TARGET */ {"gaptarget", "object", QObject::tr("Gap Target"), QObject::tr("Whether to scale the object data or mesh data")},
|
/* 55/03 LBL_RESOLUTION_MM */ {"resolution", "Standard", QObject::tr("Resolution"), QObject::tr("Resolution of part primitives, ie. how much geometry they have")},
|
||||||
/* 57/04 LBL_RESOLUTION_MM */ {"resolution", "Standard", QObject::tr("Resolution"), QObject::tr("Resolution of part primitives, ie. how much geometry they have")},
|
/* 56/04 LBL_SMOOTH_TYPE */ {"smoothtype", "edge_split", QObject::tr("Smooth Type"), QObject::tr("Use either autosmooth or an edge split modifier to smooth part faces")}
|
||||||
/* 58/05 LBL_SMOOTH_TYPE */ {"smoothtype", "edge_split", QObject::tr("Smooth Type"), QObject::tr("Use either autosmooth or an edge split modifier to smooth part faces")}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lcBlenderPreferences::ComboItems lcBlenderPreferences::mComboItemsMM [NUM_COMBO_ITEMS_MM] =
|
lcBlenderPreferences::ComboItems lcBlenderPreferences::mComboItemsMM [NUM_COMBO_ITEMS_MM] =
|
||||||
{
|
{
|
||||||
/* FIRST item set as default Data Item: */
|
/* FIRST item set as default Data Item: */
|
||||||
/* 00 LBL_CHOSEN_LOGO */ {"logo|logo2|logo3", QObject::tr("Logo (Not Used)|Logo2 (Not Used)|Flattened(3)")},
|
/* 00 LBL_CHOSEN_LOGO */ {"logo3|logo4|logo5", QObject::tr("Raised flattened logo geometry(3)|Raised rounded logo geometry(4)|Subtle rounded logo geometry(5)")},
|
||||||
/* 01 LBL_COLOUR_SCHEME_MM */ {"lgeo|ldraw|alt|custom", QObject::tr("Realistic Colours|Original LDraw Colours|Alternate LDraw Colours|Custom Colours")},
|
/* 01 LBL_COLOUR_SCHEME_MM */ {"lgeo|ldraw|alt|custom", QObject::tr("Realistic Colours|Original LDraw Colours|Alternate LDraw Colours|Custom Colours")},
|
||||||
/* 02 LBL_GAP_SCALE_STRATEGY */ {"object|constraint", QObject::tr("Gap applied directly to object|Gap scaled to adjust to gaps between parts")},
|
/* 02 LBL_COLOUR_STRATEGY */ {"material|vertex_colors", QObject::tr("Material|Vertex Colors")},
|
||||||
/* 03 LBL_GAP_TARGET */ {"object|mesh", QObject::tr("Scale object data|Scale mesh data")},
|
/* 03 LBL_RESOLUTION_MM */ {"Low|Standard|High", QObject::tr("Low Resolution Primitives|Standard Primitives|High Resolution Primitives")},
|
||||||
/* 04 LBL_RESOLUTION_MM */ {"Low|Standard|High", QObject::tr("Low Resolution Primitives|Standard Primitives|High Resolution Primitives")},
|
/* 04 LBL_SMOOTH_TYPE */ {"edge_split|auto_smooth|bmesh_split", QObject::tr("Smooth part faces with edge split modifier|Auto-smooth part faces|Split during initial mesh processing")}
|
||||||
/* 05 LBL_SMOOTH_TYPE */ {"edge_split|auto_smooth|bmesh_split", QObject::tr("Smooth part faces with edge split modifier|Auto-smooth part faces|Split during initial mesh processing")}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lcBlenderPreferences* gAddonPreferences;
|
lcBlenderPreferences* gAddonPreferences;
|
||||||
|
@ -441,31 +442,40 @@ lcBlenderPreferences::lcBlenderPreferences(int Width, int Height, double Scale,
|
||||||
mAddonGridLayout = new QGridLayout(BlenderAddonVersionBox);
|
mAddonGridLayout = new QGridLayout(BlenderAddonVersionBox);
|
||||||
BlenderAddonVersionBox->setLayout(mAddonGridLayout);
|
BlenderAddonVersionBox->setLayout(mAddonGridLayout);
|
||||||
|
|
||||||
|
QCheckBox* AddonVersionCheck = new QCheckBox(tr("Prompt to download new addon version when available"), BlenderAddonVersionBox);
|
||||||
|
AddonVersionCheck->setChecked(lcGetProfileInt(LC_PROFILE_BLENDER_ADDON_VERSION_CHECK));
|
||||||
|
QObject::connect(AddonVersionCheck, &QCheckBox::stateChanged, [](int State)
|
||||||
|
{
|
||||||
|
const bool VersionCheck = static_cast<Qt::CheckState>(State) == Qt::CheckState::Checked;
|
||||||
|
lcSetProfileInt(LC_PROFILE_BLENDER_ADDON_VERSION_CHECK, (int)VersionCheck);
|
||||||
|
});
|
||||||
|
mAddonGridLayout->addWidget(AddonVersionCheck,0,0,1,4);
|
||||||
|
|
||||||
mAddonVersionLabel = new QLabel(BlenderAddonVersionBox);
|
mAddonVersionLabel = new QLabel(BlenderAddonVersionBox);
|
||||||
mAddonGridLayout->addWidget(mAddonVersionLabel,0,0);
|
mAddonGridLayout->addWidget(mAddonVersionLabel,1,0);
|
||||||
|
|
||||||
mAddonVersionEdit = new QLineEdit(BlenderAddonVersionBox);
|
mAddonVersionEdit = new QLineEdit(BlenderAddonVersionBox);
|
||||||
mAddonVersionEdit->setToolTip(tr("%1 Blender LDraw import and image renderer addon").arg(LC_PRODUCTNAME_STR));
|
mAddonVersionEdit->setToolTip(tr("%1 Blender LDraw import and image renderer addon").arg(LC_PRODUCTNAME_STR));
|
||||||
mAddonVersionEdit->setPalette(ReadOnlyPalette);
|
mAddonVersionEdit->setPalette(ReadOnlyPalette);
|
||||||
mAddonVersionEdit->setReadOnly(true);
|
mAddonVersionEdit->setReadOnly(true);
|
||||||
mAddonGridLayout->addWidget(mAddonVersionEdit,0,1);
|
mAddonGridLayout->addWidget(mAddonVersionEdit,1,1);
|
||||||
mAddonGridLayout->setColumnStretch(1,1/*1 is greater than 0 (default)*/);
|
mAddonGridLayout->setColumnStretch(1,1/*1 is greater than 0 (default)*/);
|
||||||
|
|
||||||
mAddonUpdateButton = new QPushButton(tr("Update"), BlenderAddonVersionBox);
|
mAddonUpdateButton = new QPushButton(tr("Update"), BlenderAddonVersionBox);
|
||||||
mAddonUpdateButton->setToolTip(tr("Update %1 Blender LDraw addon").arg(LC_PRODUCTNAME_STR));
|
mAddonUpdateButton->setToolTip(tr("Update %1 Blender LDraw addon").arg(LC_PRODUCTNAME_STR));
|
||||||
mAddonGridLayout->addWidget(mAddonUpdateButton,0,2);
|
mAddonGridLayout->addWidget(mAddonUpdateButton,1,2);
|
||||||
connect(mAddonUpdateButton, SIGNAL(clicked(bool)), this, SLOT(UpdateBlenderAddon()));
|
connect(mAddonUpdateButton, SIGNAL(clicked(bool)), this, SLOT(UpdateBlenderAddon()));
|
||||||
|
|
||||||
mAddonStdOutButton = new QPushButton(tr("Output..."), BlenderAddonVersionBox);
|
mAddonStdOutButton = new QPushButton(tr("Output..."), BlenderAddonVersionBox);
|
||||||
mAddonStdOutButton->setToolTip(tr("Open the standrd output log"));
|
mAddonStdOutButton->setToolTip(tr("Open the standrd output log"));
|
||||||
mAddonStdOutButton->setEnabled(false);
|
mAddonStdOutButton->setEnabled(false);
|
||||||
mAddonGridLayout->addWidget(mAddonStdOutButton,0,3);
|
mAddonGridLayout->addWidget(mAddonStdOutButton,1,3);
|
||||||
connect(mAddonStdOutButton, SIGNAL(clicked(bool)), this, SLOT(GetStandardOutput()));
|
connect(mAddonStdOutButton, SIGNAL(clicked(bool)), this, SLOT(GetStandardOutput()));
|
||||||
|
|
||||||
mModulesBox = new QGroupBox(tr("Enabled Addon Modules"),mContent);
|
mModulesBox = new QGroupBox(tr("Enabled Addon Modules"),mContent);
|
||||||
QHBoxLayout* ModulesLayout = new QHBoxLayout(mModulesBox);
|
QHBoxLayout* ModulesLayout = new QHBoxLayout(mModulesBox);
|
||||||
mModulesBox->setLayout(ModulesLayout);
|
mModulesBox->setLayout(ModulesLayout);
|
||||||
mAddonGridLayout->addWidget(mModulesBox,1,0,1,4);
|
mAddonGridLayout->addWidget(mModulesBox,2,0,1,4);
|
||||||
|
|
||||||
mImportActBox = new QCheckBox(tr("LDraw Import TN"),mModulesBox);
|
mImportActBox = new QCheckBox(tr("LDraw Import TN"),mModulesBox);
|
||||||
mImportActBox->setToolTip(tr("Enable addon import module (adapted from LDraw Import by Toby Nelson) in Blender"));
|
mImportActBox->setToolTip(tr("Enable addon import module (adapted from LDraw Import by Toby Nelson) in Blender"));
|
||||||
|
@ -1440,18 +1450,25 @@ bool lcBlenderPreferences::GetBlenderAddon(const QString& BlenderDir)
|
||||||
}
|
}
|
||||||
else if (gMainWindow)
|
else if (gMainWindow)
|
||||||
{
|
{
|
||||||
if (LocalVersion.isEmpty())
|
if (lcGetProfileInt(LC_PROFILE_BLENDER_ADDON_VERSION_CHECK))
|
||||||
LocalVersion = gAddonPreferences->mAddonVersion;
|
|
||||||
const QString& Title = tr ("%1 Blender LDraw Addon").arg(LC_PRODUCTNAME_STR);
|
|
||||||
const QString& Header = tr ("Detected %1 Blender LDraw addon %2. A newer version %3 exists.").arg(LC_PRODUCTNAME_STR).arg(LocalVersion).arg(OnlineVersion);
|
|
||||||
const QString& Body = tr ("Do you want to download version %1 ?").arg(OnlineVersion);
|
|
||||||
int Exec = ShowMessage(Header, Title, Body, QString(), MBB_YES, QMessageBox::NoIcon);
|
|
||||||
if (Exec == QMessageBox::Cancel)
|
|
||||||
{
|
{
|
||||||
AddonStatus = tr("Blender addon setup cancelled");
|
if (LocalVersion.isEmpty())
|
||||||
AddonAction = ADDON_CANCEL;
|
LocalVersion = gAddonPreferences->mAddonVersion;
|
||||||
|
const QString& Title = tr ("%1 Blender LDraw Addon").arg(LC_PRODUCTNAME_STR);
|
||||||
|
const QString& Header = tr ("Detected %1 Blender LDraw addon %2. A newer version %3 exists.").arg(LC_PRODUCTNAME_STR).arg(LocalVersion).arg(OnlineVersion);
|
||||||
|
const QString& Body = tr ("Do you want to download version %1 ?").arg(OnlineVersion);
|
||||||
|
int Exec = ShowMessage(Header, Title, Body, QString(), MBB_YES, QMessageBox::NoIcon);
|
||||||
|
if (Exec == QMessageBox::Cancel)
|
||||||
|
{
|
||||||
|
AddonStatus = tr("Blender addon setup cancelled");
|
||||||
|
AddonAction = ADDON_CANCEL;
|
||||||
|
}
|
||||||
|
else if (Exec == QMessageBox::No)
|
||||||
|
{
|
||||||
|
AddonAction = ADDON_RELOAD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (Exec == QMessageBox::No)
|
else
|
||||||
{
|
{
|
||||||
AddonAction = ADDON_RELOAD;
|
AddonAction = ADDON_RELOAD;
|
||||||
}
|
}
|
||||||
|
@ -2586,7 +2603,9 @@ void lcBlenderPreferences::SaveSettings()
|
||||||
continue;
|
continue;
|
||||||
Key = mBlenderPaths[LblIdx].key;
|
Key = mBlenderPaths[LblIdx].key;
|
||||||
Value = QDir::toNativeSeparators(mBlenderPaths[LblIdx].value);
|
Value = QDir::toNativeSeparators(mBlenderPaths[LblIdx].value);
|
||||||
Settings.setValue(Key, QVariant(Value));
|
|
||||||
|
if (Settings.contains(Key))
|
||||||
|
Settings.setValue(Key, QVariant(Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int LblIdx = 0; LblIdx < NumSettings(); LblIdx++)
|
for (int LblIdx = 0; LblIdx < NumSettings(); LblIdx++)
|
||||||
|
@ -2608,7 +2627,9 @@ void lcBlenderPreferences::SaveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
Key = mBlenderSettings[LblIdx].key;
|
Key = mBlenderSettings[LblIdx].key;
|
||||||
Settings.setValue(Key, QVariant(Value));
|
|
||||||
|
if (Settings.contains(Key))
|
||||||
|
Settings.setValue(Key, QVariant(Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.setValue(parameterFileKey, QVariant(QDir::toNativeSeparators(ParameterFile)));
|
Settings.setValue(parameterFileKey, QVariant(QDir::toNativeSeparators(ParameterFile)));
|
||||||
|
@ -2625,7 +2646,9 @@ void lcBlenderPreferences::SaveSettings()
|
||||||
continue;
|
continue;
|
||||||
Key = mBlenderPaths[LblIdx].key_mm;
|
Key = mBlenderPaths[LblIdx].key_mm;
|
||||||
Value = QDir::toNativeSeparators(mBlenderPaths[LblIdx].value);
|
Value = QDir::toNativeSeparators(mBlenderPaths[LblIdx].value);
|
||||||
Settings.setValue(Key, QVariant(Value));
|
|
||||||
|
if (Settings.contains(Key))
|
||||||
|
Settings.setValue(Key, QVariant(Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int LblIdx = 0; LblIdx < NumSettingsMM(); LblIdx++)
|
for (int LblIdx = 0; LblIdx < NumSettingsMM(); LblIdx++)
|
||||||
|
@ -2644,7 +2667,9 @@ void lcBlenderPreferences::SaveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
Key = mBlenderSettingsMM[LblIdx].key;
|
Key = mBlenderSettingsMM[LblIdx].key;
|
||||||
Settings.setValue(Key, QVariant(Value));
|
|
||||||
|
if (Settings.contains(Key))
|
||||||
|
Settings.setValue(Key, QVariant(Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
searchDirectoriesKey = QLatin1String("additionalSearchPaths");
|
searchDirectoriesKey = QLatin1String("additionalSearchPaths");
|
||||||
|
@ -3462,6 +3487,20 @@ int lcBlenderPreferences::ShowMessage(const QString& Header, const QString& Tit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool DownloadRequest = Body.startsWith(tr("Do you want to download version "));
|
||||||
|
|
||||||
|
if (DownloadRequest){
|
||||||
|
QCheckBox* AddonVersionCheck = new QCheckBox(tr("Do not show download new addon version message again."));
|
||||||
|
Box.setCheckBox(AddonVersionCheck);
|
||||||
|
QObject::connect(AddonVersionCheck, &QCheckBox::stateChanged, [](int State)
|
||||||
|
{
|
||||||
|
bool VersionCheck = true;
|
||||||
|
if (static_cast<Qt::CheckState>(State) == Qt::CheckState::Checked)
|
||||||
|
VersionCheck = false;
|
||||||
|
lcSetProfileInt(LC_PROFILE_BLENDER_ADDON_VERSION_CHECK, (int)VersionCheck);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return Box.exec();
|
return Box.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,30 +237,30 @@ private:
|
||||||
LBL_ADD_ENVIRONMENT_MM, // 0 QCheckBox
|
LBL_ADD_ENVIRONMENT_MM, // 0 QCheckBox
|
||||||
LBL_BEVEL_EDGES_MM, // 1 QCheckBox
|
LBL_BEVEL_EDGES_MM, // 1 QCheckBox
|
||||||
LBL_BLEND_FILE_TRUSTED_MM, // 2 QCheckBox
|
LBL_BLEND_FILE_TRUSTED_MM, // 2 QCheckBox
|
||||||
LBL_CROP_IMAGE_MM, // 3 QCheckBox
|
LBL_CASE_SENSITIVE_FILESYSTEM, // 3 QCheckBox
|
||||||
LBL_DISPLAY_LOGO, // 4 QCheckBox
|
LBL_CROP_IMAGE_MM, // 4 QCheckBox
|
||||||
LBL_IMPORT_CAMERAS_MM, // 5 QCheckBox
|
LBL_DISPLAY_LOGO, // 5 QCheckBox
|
||||||
LBL_IMPORT_EDGES, // 6 QCheckBox
|
LBL_IMPORT_CAMERAS_MM, // 6 QCheckBox
|
||||||
NUM_COMBO_ITEMS_MM, // 7
|
NUM_COMBO_ITEMS_MM, // 7
|
||||||
LBL_IMPORT_LIGHTS_MM = NUM_COMBO_ITEMS_MM, // 7 QCheckBox
|
LBL_IMPORT_EDGES = NUM_COMBO_ITEMS_MM, // 7 QCheckBox
|
||||||
LBL_KEEP_ASPECT_RATIO_MM, // 8 QCheckBox
|
LBL_IMPORT_LIGHTS_MM, // 8 QCheckBox
|
||||||
LBL_MAKE_GAPS, // 9 QCheckBox
|
LBL_KEEP_ASPECT_RATIO_MM, // 9 QCheckBox
|
||||||
LBL_META_BFC, // 10 QCheckBox
|
LBL_MAKE_GAPS, // 10 QCheckBox
|
||||||
LBL_META_CLEAR, // 11 QCheckBox
|
LBL_META_BFC, // 11 QCheckBox
|
||||||
LBL_META_GROUP, // 12 QCheckBox
|
LBL_META_CLEAR, // 12 QCheckBox
|
||||||
LBL_META_PAUSE, // 13 QCheckBox
|
LBL_META_GROUP, // 13 QCheckBox
|
||||||
LBL_META_PRINT_WRITE, // 14 QCheckBox
|
LBL_META_PAUSE, // 14 QCheckBox
|
||||||
LBL_META_SAVE, // 15 QCheckBox
|
LBL_META_PRINT_WRITE, // 15 QCheckBox
|
||||||
LBL_META_STEP, // 16 QCheckBox
|
LBL_META_SAVE, // 16 QCheckBox
|
||||||
LBL_META_STEP_GROUPS, // 17 QCheckBox
|
LBL_META_STEP, // 17 QCheckBox
|
||||||
LBL_META_TEXMAP, // 18 QCheckBox
|
LBL_META_STEP_GROUPS, // 18 QCheckBox
|
||||||
LBL_NO_STUDS, // 19 QCheckBox
|
LBL_META_TEXMAP, // 19 QCheckBox
|
||||||
LBL_OVERWRITE_IMAGE_MM, // 20 QCheckBox
|
LBL_NO_STUDS, // 20 QCheckBox
|
||||||
LBL_POSITION_CAMERA_MM, // 21 QCheckBox
|
LBL_OVERWRITE_IMAGE_MM, // 21 QCheckBox
|
||||||
LBL_PARENT_TO_EMPTY, // 22 QCheckBox
|
LBL_POSITION_CAMERA_MM, // 22 QCheckBox
|
||||||
LBL_PREFER_STUDIO, // 23 QCheckBox
|
LBL_PARENT_TO_EMPTY, // 23 QCheckBox
|
||||||
LBL_PREFER_UNOFFICIAL, // 24 QCheckBox
|
LBL_PREFER_STUDIO, // 24 QCheckBox
|
||||||
LBL_PRESERVE_HIERARCHY, // 25 QCheckBox
|
LBL_PREFER_UNOFFICIAL, // 25 QCheckBox
|
||||||
LBL_PROFILE, // 26 QCheckBox
|
LBL_PROFILE, // 26 QCheckBox
|
||||||
LBL_RECALCULATE_NORMALS, // 27 QCheckBox
|
LBL_RECALCULATE_NORMALS, // 27 QCheckBox
|
||||||
LBL_REMOVE_DOUBLES_MM, // 28 QCheckBox
|
LBL_REMOVE_DOUBLES_MM, // 28 QCheckBox
|
||||||
|
@ -270,32 +270,30 @@ private:
|
||||||
LBL_SET_TIMELINE_MARKERS, // 32 QCheckBox
|
LBL_SET_TIMELINE_MARKERS, // 32 QCheckBox
|
||||||
LBL_SHADE_SMOOTH, // 33 QCheckBox
|
LBL_SHADE_SMOOTH, // 33 QCheckBox
|
||||||
LBL_TRANSPARENT_BACKGROUND_MM, // 34 QCheckBox
|
LBL_TRANSPARENT_BACKGROUND_MM, // 34 QCheckBox
|
||||||
LBL_TREAT_MODELS_WITH_SUBPARTS_AS_PARTS, // 35 QCheckBox
|
LBL_TREAT_SHORTCUT_AS_MODEL, // 35 QCheckBox
|
||||||
LBL_TREAT_SHORTCUT_AS_MODEL, // 36 QCheckBox
|
LBL_TRIANGULATE, // 36 QCheckBox
|
||||||
LBL_TRIANGULATE, // 37 QCheckBox
|
LBL_USE_ARCHIVE_LIBRARY_MM, // 37 QCheckBox
|
||||||
LBL_USE_ARCHIVE_LIBRARY_MM, // 38 QCheckBox
|
LBL_USE_FREESTYLE_EDGES, // 38 QCheckBox
|
||||||
LBL_USE_FREESTYLE_EDGES, // 39 QCheckBox
|
LBL_VERBOSE_MM, // 39 QCheckBox
|
||||||
LBL_VERBOSE_MM, // 40 QCheckBox
|
|
||||||
|
|
||||||
LBL_BEVEL_SEGMENTS, // 41/ 0 QLineEdit
|
LBL_BEVEL_SEGMENTS, // 40/ 0 QLineEdit
|
||||||
LBL_BEVEL_WEIGHT, // 42/ 1 QLineEdit
|
LBL_BEVEL_WEIGHT, // 41/ 1 QLineEdit
|
||||||
LBL_BEVEL_WIDTH_MM, // 43/ 2 QLineEdit
|
LBL_BEVEL_WIDTH_MM, // 42/ 2 QLineEdit
|
||||||
LBL_CAMERA_BORDER_PERCENT_MM, // 44/ 3 QLineEdit
|
LBL_CAMERA_BORDER_PERCENT_MM, // 43/ 3 QLineEdit
|
||||||
LBL_FRAMES_PER_STEP, // 45/ 4 QLineEdit
|
LBL_FRAMES_PER_STEP, // 44/ 4 QLineEdit
|
||||||
LBL_GAP_SCALE, // 46/ 5 QLineEdit
|
LBL_GAP_SCALE, // 45/ 5 QLineEdit
|
||||||
LBL_IMPORT_SCALE, // 47/ 6 QLineEdit
|
LBL_IMPORT_SCALE, // 46/ 6 QLineEdit
|
||||||
LBL_MERGE_DISTANCE, // 48/ 7 QLineEdit
|
LBL_MERGE_DISTANCE, // 47/ 7 QLineEdit
|
||||||
LBL_RENDER_PERCENTAGE_MM, // 49/ 8 QLineEdit
|
LBL_RENDER_PERCENTAGE_MM, // 48/ 8 QLineEdit
|
||||||
LBL_RESOLUTION_WIDTH, // 50/ 9 QLineEdit
|
LBL_RESOLUTION_WIDTH, // 49/ 9 QLineEdit
|
||||||
LBL_RESOLUTION_HEIGHT, // 51/10 QLineEdit
|
LBL_RESOLUTION_HEIGHT, // 50/10 QLineEdit
|
||||||
LBL_STARTING_STEP_FRAME, // 52/11 QLineEdit
|
LBL_STARTING_STEP_FRAME, // 51/11 QLineEdit
|
||||||
|
|
||||||
LBL_CHOSEN_LOGO, // 53/ 0 QComboBox
|
LBL_CHOSEN_LOGO, // 52/ 0 QComboBox
|
||||||
LBL_COLOUR_SCHEME_MM, // 54/ 1 QComboBox
|
LBL_COLOUR_SCHEME_MM, // 53/ 1 QComboBox
|
||||||
LBL_GAP_SCALE_STRATEGY, // 55/ 2 QComboBox
|
LBL_COLOUR_STRATEGY, // 54/ 2 QComboBox
|
||||||
LBL_GAP_TARGET, // 56/ 3 QComboBox
|
LBL_RESOLUTION_MM, // 55/ 3 QComboBox
|
||||||
LBL_RESOLUTION_MM, // 57/ 4 QComboBox
|
LBL_SMOOTH_TYPE, // 56/ 4 QComboBox
|
||||||
LBL_SMOOTH_TYPE, // 58/ 5 QComboBox
|
|
||||||
|
|
||||||
NUM_SETTINGS_MM
|
NUM_SETTINGS_MM
|
||||||
};
|
};
|
||||||
|
@ -311,42 +309,41 @@ private:
|
||||||
CTL_COLOUR_SCHEME_COMBO_MM = CTL_BEVEL_EDGES_BOX_MM, // 1
|
CTL_COLOUR_SCHEME_COMBO_MM = CTL_BEVEL_EDGES_BOX_MM, // 1
|
||||||
CTL_BLEND_FILE_TRUSTED_BOX_MM, // 2
|
CTL_BLEND_FILE_TRUSTED_BOX_MM, // 2
|
||||||
CTL_BEVEL_WIDTH_EDIT_MM = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
|
CTL_BEVEL_WIDTH_EDIT_MM = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
|
||||||
CTL_GAP_SCALE_STRATEGY_COMBO = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
|
CTL_COLOUR_STRATEGY_COMBO = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
|
||||||
CTL_CROP_IMAGE_BOX_MM, // 3
|
CTL_CASE_SENSITIVE_FILESYSTEM_BOX, // 3
|
||||||
CTL_CAMERA_BORDER_PERCENT_EDIT_MM = CTL_CROP_IMAGE_BOX_MM, // 3
|
CTL_CAMERA_BORDER_PERCENT_EDIT_MM = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
|
||||||
CTL_GAP_TARGET_COMBO = CTL_CROP_IMAGE_BOX_MM, // 3
|
CTL_RESOLUTION_COMBO_MM = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
|
||||||
CTL_DISPLAY_LOGO_BOX, // 4
|
CTL_CROP_IMAGE_BOX_MM, // 4
|
||||||
CTL_FRAMES_PER_STEP_EDIT = CTL_DISPLAY_LOGO_BOX, // 4
|
CTL_FRAMES_PER_STEP_EDIT = CTL_CROP_IMAGE_BOX_MM, // 4
|
||||||
CTL_RESOLUTION_COMBO_MM = CTL_DISPLAY_LOGO_BOX, // 4
|
CTL_SMOOTH_TYPE_COMBO = CTL_CROP_IMAGE_BOX_MM, // 4
|
||||||
CTL_IMPORT_CAMERAS_BOX_MM, // 5
|
CTL_DISPLAY_LOGO_BOX, // 5
|
||||||
CTL_GAP_SCALE_EDIT = CTL_IMPORT_CAMERAS_BOX_MM, // 5
|
CTL_GAP_SCALE_EDIT = CTL_DISPLAY_LOGO_BOX, // 5
|
||||||
CTL_SMOOTH_TYPE_COMBO = CTL_IMPORT_CAMERAS_BOX_MM, // 5
|
CTL_IMPORT_CAMERAS_BOX_MM, // 6
|
||||||
CTL_IMPORT_EDGES_BOX, // 6
|
CTL_IMPORT_SCALE_EDIT = CTL_IMPORT_CAMERAS_BOX_MM, // 6
|
||||||
CTL_IMPORT_SCALE_EDIT = CTL_IMPORT_EDGES_BOX, // 6
|
CTL_IMPORT_EDGES_BOX, // 7
|
||||||
CTL_IMPORT_LIGHTS_BOX_MM, // 7
|
CTL_MERGE_DISTANCE_EDIT = CTL_IMPORT_EDGES_BOX, // 7
|
||||||
CTL_MERGE_DISTANCE_EDIT = CTL_IMPORT_LIGHTS_BOX_MM, // 7
|
CTL_IMPORT_LIGHTS_BOX_MM, // 8
|
||||||
CTL_KEEP_ASPECT_RATIO_BOX_MM, // 8
|
CTL_RENDER_PERCENTAGE_EDIT_MM = CTL_IMPORT_LIGHTS_BOX_MM, // 8
|
||||||
CTL_RENDER_PERCENTAGE_EDIT_MM = CTL_KEEP_ASPECT_RATIO_BOX_MM, // 8
|
CTL_KEEP_ASPECT_RATIO_BOX_MM, // 9
|
||||||
CTL_MAKE_GAPS_BOX, // 9
|
CTL_RESOLUTION_WIDTH_EDIT = CTL_KEEP_ASPECT_RATIO_BOX_MM, // 9
|
||||||
CTL_RESOLUTION_WIDTH_EDIT = CTL_MAKE_GAPS_BOX, // 9
|
CTL_MAKE_GAPS_BOX, // 10
|
||||||
CTL_META_BFC_BOX, // 10
|
CTL_RESOLUTION_HEIGHT_EDIT = CTL_MAKE_GAPS_BOX, // 10
|
||||||
CTL_RESOLUTION_HEIGHT_EDIT = CTL_META_BFC_BOX, // 10
|
CTL_META_BFC_BOX, // 11
|
||||||
CTL_META_CLEAR_BOX, // 11
|
CTL_STARTING_STEP_FRAME_EDIT = CTL_META_BFC_BOX, // 11
|
||||||
CTL_STARTING_STEP_FRAME_EDIT = CTL_META_CLEAR_BOX, // 11
|
CTL_META_CLEAR_BOX, // 12
|
||||||
CTL_META_GROUP_BOX, // 12
|
CTL_META_GROUP_BOX, // 13
|
||||||
CTL_META_PAUSE_BOX, // 13
|
CTL_META_PAUSE_BOX, // 14
|
||||||
CTL_META_PRINT_WRITE_BOX, // 14
|
CTL_META_PRINT_WRITE_BOX, // 15
|
||||||
CTL_META_SAVE_BOX, // 15
|
CTL_META_SAVE_BOX, // 16
|
||||||
CTL_META_STEP_BOX, // 16
|
CTL_META_STEP_BOX, // 17
|
||||||
CTL_META_STEP_GROUPS_BOX, // 17
|
CTL_META_STEP_GROUPS_BOX, // 18
|
||||||
CTL_META_TEXMAP_BOX, // 18
|
CTL_META_TEXMAP_BOX, // 19
|
||||||
CTL_NO_STUDS_BOX, // 19
|
CTL_NO_STUDS_BOX, // 20
|
||||||
CTL_POSITION_CAMERA_BOX_MM, // 10
|
CTL_POSITION_CAMERA_BOX_MM, // 21
|
||||||
CTL_OVERWRITE_IMAGE_BOX_MM, // 21
|
CTL_OVERWRITE_IMAGE_BOX_MM, // 22
|
||||||
CTL_PARENT_TO_EMPTY_BOX, // 22
|
CTL_PARENT_TO_EMPTY_BOX, // 23
|
||||||
CTL_PREFER_STUDIO_BOX, // 23
|
CTL_PREFER_STUDIO_BOX, // 24
|
||||||
CTL_PREFER_UNOFFICIAL_BOX, // 24
|
CTL_PREFER_UNOFFICIAL_BOX, // 25
|
||||||
CTL_PRESERVE_HIERARCHY_BOX, // 25
|
|
||||||
CTL_PROFILE_BOX, // 26
|
CTL_PROFILE_BOX, // 26
|
||||||
CTL_RECALCULATE_NORMALS_BOX, // 27
|
CTL_RECALCULATE_NORMALS_BOX, // 27
|
||||||
CTL_REMOVE_DOUBLES_BOX_MM, // 28
|
CTL_REMOVE_DOUBLES_BOX_MM, // 28
|
||||||
|
@ -356,12 +353,11 @@ private:
|
||||||
CTL_SET_TIMELINE_MARKERS_BOX, // 32
|
CTL_SET_TIMELINE_MARKERS_BOX, // 32
|
||||||
CTL_SHADE_SMOOTH_BOX, // 33
|
CTL_SHADE_SMOOTH_BOX, // 33
|
||||||
CTL_TRANSPARENT_BACKGROUND_BOX_MM, // 34
|
CTL_TRANSPARENT_BACKGROUND_BOX_MM, // 34
|
||||||
CTL_TREAT_MODELS_WITH_SUBPARTS_AS_PARTS_BOX, // 35
|
CTL_TREAT_SHORTCUT_AS_MODEL_BOX, // 35
|
||||||
CTL_TREAT_SHORTCUT_AS_MODEL_BOX, // 36
|
CTL_TRIANGULATE_BOX, // 36
|
||||||
CTL_TRIANGULATE_BOX, // 37
|
CTL_USE_ARCHIVE_LIBRARY_BOX_MM, // 37
|
||||||
CTL_USE_ARCHIVE_LIBRARY_BOX_MM, // 38
|
CTL_USE_FREESTYLE_EDGES_BOX, // 38
|
||||||
CTL_USE_FREESTYLE_EDGES_BOX, // 39
|
CTL_VERBOSE_BOX_MM // 39
|
||||||
CTL_VERBOSE_BOX_MM // 40
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BlenderBrickType
|
enum BlenderBrickType
|
||||||
|
|
|
@ -85,6 +85,8 @@ static std::vector<lcColor> lcParseColorFile(lcFile& File)
|
||||||
|
|
||||||
Color.Code = ~0U;
|
Color.Code = ~0U;
|
||||||
Color.Translucent = false;
|
Color.Translucent = false;
|
||||||
|
Color.Chrome = false;
|
||||||
|
Color.Rubber = false;
|
||||||
Color.Group = LC_COLORGROUP_SOLID;
|
Color.Group = LC_COLORGROUP_SOLID;
|
||||||
Color.Value[0] = FLT_MAX;
|
Color.Value[0] = FLT_MAX;
|
||||||
Color.Value[1] = FLT_MAX;
|
Color.Value[1] = FLT_MAX;
|
||||||
|
@ -157,8 +159,17 @@ static std::vector<lcColor> lcParseColorFile(lcFile& File)
|
||||||
else if (Value != 0)
|
else if (Value != 0)
|
||||||
Color.Group = LC_COLORGROUP_SPECIAL;
|
Color.Group = LC_COLORGROUP_SPECIAL;
|
||||||
}
|
}
|
||||||
else if (!strcmp(Token, "CHROME") || !strcmp(Token, "PEARLESCENT") || !strcmp(Token, "RUBBER") ||
|
else if (!strcmp(Token, "CHROME"))
|
||||||
!strcmp(Token, "MATTE_METALIC") || !strcmp(Token, "METAL") || !strcmp(Token, "LUMINANCE"))
|
{
|
||||||
|
Color.Chrome = true;
|
||||||
|
Color.Group = LC_COLORGROUP_SPECIAL;
|
||||||
|
}
|
||||||
|
else if (!strcmp(Token, "RUBBER"))
|
||||||
|
{
|
||||||
|
Color.Rubber = true;
|
||||||
|
Color.Group = LC_COLORGROUP_SPECIAL;
|
||||||
|
}
|
||||||
|
else if (!strcmp(Token, "PEARLESCENT") || !strcmp(Token, "MATTE_METALIC") || !strcmp(Token, "METAL") || !strcmp(Token, "LUMINANCE"))
|
||||||
{
|
{
|
||||||
Color.Group = LC_COLORGROUP_SPECIAL;
|
Color.Group = LC_COLORGROUP_SPECIAL;
|
||||||
}
|
}
|
||||||
|
@ -236,6 +247,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
||||||
|
|
||||||
MainColor.Code = 16;
|
MainColor.Code = 16;
|
||||||
MainColor.Translucent = false;
|
MainColor.Translucent = false;
|
||||||
|
MainColor.Chrome = false;
|
||||||
|
MainColor.Rubber = false;
|
||||||
MainColor.Group = LC_COLORGROUP_SOLID;
|
MainColor.Group = LC_COLORGROUP_SOLID;
|
||||||
MainColor.Value[0] = 1.0f;
|
MainColor.Value[0] = 1.0f;
|
||||||
MainColor.Value[1] = 1.0f;
|
MainColor.Value[1] = 1.0f;
|
||||||
|
@ -257,6 +270,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
||||||
|
|
||||||
EdgeColor.Code = 24;
|
EdgeColor.Code = 24;
|
||||||
EdgeColor.Translucent = false;
|
EdgeColor.Translucent = false;
|
||||||
|
EdgeColor.Chrome = false;
|
||||||
|
EdgeColor.Rubber = false;
|
||||||
EdgeColor.Group = LC_NUM_COLORGROUPS;
|
EdgeColor.Group = LC_NUM_COLORGROUPS;
|
||||||
EdgeColor.Value[0] = 0.5f;
|
EdgeColor.Value[0] = 0.5f;
|
||||||
EdgeColor.Value[1] = 0.5f;
|
EdgeColor.Value[1] = 0.5f;
|
||||||
|
@ -279,6 +294,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
||||||
|
|
||||||
StudCylinderColor.Code = LC_STUD_CYLINDER_COLOR_CODE;
|
StudCylinderColor.Code = LC_STUD_CYLINDER_COLOR_CODE;
|
||||||
StudCylinderColor.Translucent = false;
|
StudCylinderColor.Translucent = false;
|
||||||
|
StudCylinderColor.Chrome = false;
|
||||||
|
StudCylinderColor.Rubber = false;
|
||||||
StudCylinderColor.Group = LC_NUM_COLORGROUPS;
|
StudCylinderColor.Group = LC_NUM_COLORGROUPS;
|
||||||
StudCylinderColor.Value = lcVector4FromColor(Preferences.mStudCylinderColor);
|
StudCylinderColor.Value = lcVector4FromColor(Preferences.mStudCylinderColor);
|
||||||
StudCylinderColor.Edge = lcVector4FromColor(Preferences.mPartEdgeColor);
|
StudCylinderColor.Edge = lcVector4FromColor(Preferences.mPartEdgeColor);
|
||||||
|
@ -294,6 +311,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
||||||
|
|
||||||
NoColor.Code = LC_COLOR_NOCOLOR;
|
NoColor.Code = LC_COLOR_NOCOLOR;
|
||||||
NoColor.Translucent = false;
|
NoColor.Translucent = false;
|
||||||
|
NoColor.Chrome = false;
|
||||||
|
NoColor.Rubber = false;
|
||||||
NoColor.Group = LC_NUM_COLORGROUPS;
|
NoColor.Group = LC_NUM_COLORGROUPS;
|
||||||
NoColor.Value[0] = 0.5f;
|
NoColor.Value[0] = 0.5f;
|
||||||
NoColor.Value[1] = 0.5f;
|
NoColor.Value[1] = 0.5f;
|
||||||
|
@ -362,6 +381,8 @@ int lcGetColorIndex(quint32 ColorCode)
|
||||||
|
|
||||||
Color.Code = ColorCode;
|
Color.Code = ColorCode;
|
||||||
Color.Translucent = false;
|
Color.Translucent = false;
|
||||||
|
Color.Chrome = false;
|
||||||
|
Color.Rubber = false;
|
||||||
Color.Edge[0] = 0.2f;
|
Color.Edge[0] = 0.2f;
|
||||||
Color.Edge[1] = 0.2f;
|
Color.Edge[1] = 0.2f;
|
||||||
Color.Edge[2] = 0.2f;
|
Color.Edge[2] = 0.2f;
|
||||||
|
|
|
@ -13,6 +13,8 @@ struct lcColor
|
||||||
quint32 Code;
|
quint32 Code;
|
||||||
int Group;
|
int Group;
|
||||||
bool Translucent = false;
|
bool Translucent = false;
|
||||||
|
bool Chrome = false;
|
||||||
|
bool Rubber = false;
|
||||||
bool Adjusted = false;
|
bool Adjusted = false;
|
||||||
lcVector4 Value;
|
lcVector4 Value;
|
||||||
lcVector4 Edge;
|
lcVector4 Edge;
|
||||||
|
@ -64,3 +66,13 @@ inline bool lcIsColorTranslucent(size_t ColorIndex)
|
||||||
{
|
{
|
||||||
return gColorList[ColorIndex].Translucent;
|
return gColorList[ColorIndex].Translucent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool lcIsColorChrome(size_t ColorIndex)
|
||||||
|
{
|
||||||
|
return gColorList[ColorIndex].Chrome;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool lcIsColorRubber(size_t ColorIndex)
|
||||||
|
{
|
||||||
|
return gColorList[ColorIndex].Rubber;
|
||||||
|
}
|
||||||
|
|
|
@ -333,46 +333,46 @@ const lcCommand gCommands[] =
|
||||||
QT_TRANSLATE_NOOP("Status", "Select all pieces of the same type and color"),
|
QT_TRANSLATE_NOOP("Status", "Select all pieces of the same type and color"),
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_EDIT_TRANSFORM_RELATIVE
|
// LC_EDIT_TRANSFORM_RELATIVE
|
||||||
{
|
{
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformRelative"),
|
QT_TRANSLATE_NOOP("Action", "Edit.TransformRelative"),
|
||||||
QT_TRANSLATE_NOOP("Menu", "Relative Transforms"),
|
QT_TRANSLATE_NOOP("Menu", "Relative Transforms"),
|
||||||
QT_TRANSLATE_NOOP("Status", "Move and rotate objects relative to the one that has focus"),
|
QT_TRANSLATE_NOOP("Status", "Move and rotate objects relative to the one that has focus"),
|
||||||
""
|
|
||||||
},
|
|
||||||
// LC_EDIT_TRANSFORM_ABSOLUTE
|
|
||||||
{
|
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformAbsolute"),
|
|
||||||
QT_TRANSLATE_NOOP("Menu", "Absolute Transforms"),
|
|
||||||
QT_TRANSLATE_NOOP("Status", "Move and rotate objects in absolute coordinates"),
|
|
||||||
""
|
|
||||||
},
|
|
||||||
// LC_EDIT_TRANSFORM_TOGGLE_RELATIVE
|
|
||||||
{
|
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleRelative"),
|
|
||||||
QT_TRANSLATE_NOOP("Menu", "Toggle Relative Transforms"),
|
|
||||||
QT_TRANSLATE_NOOP("Status", "Toggle moving and rotating objects relative to the one that has focus"),
|
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_EDIT_TRANSFORM_SEPARATELY
|
// LC_EDIT_TRANSFORM_ABSOLUTE
|
||||||
{
|
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformSeparately"),
|
|
||||||
QT_TRANSLATE_NOOP("Menu", "Rotate Separately"),
|
|
||||||
QT_TRANSLATE_NOOP("Status", "Rotate selected pieces separately"),
|
|
||||||
""
|
|
||||||
},
|
|
||||||
// LC_EDIT_TRANSFORM_TOGETHER
|
|
||||||
{
|
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformTogether"),
|
|
||||||
QT_TRANSLATE_NOOP("Menu", "Rotate Together"),
|
|
||||||
QT_TRANSLATE_NOOP("Status", "Rotate selected pieces together"),
|
|
||||||
""
|
|
||||||
},
|
|
||||||
// LC_EDIT_TRANSFORM_TOGGLE_SEPARATE
|
|
||||||
{
|
{
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleSeparate"),
|
QT_TRANSLATE_NOOP("Action", "Edit.TransformAbsolute"),
|
||||||
QT_TRANSLATE_NOOP("Menu", "Toggle Separate Transforms"),
|
QT_TRANSLATE_NOOP("Menu", "Absolute Transforms"),
|
||||||
QT_TRANSLATE_NOOP("Status", "Toggle rotating selected pieces separately"),
|
QT_TRANSLATE_NOOP("Status", "Move and rotate objects in absolute coordinates"),
|
||||||
|
""
|
||||||
|
},
|
||||||
|
// LC_EDIT_TRANSFORM_TOGGLE_RELATIVE
|
||||||
|
{
|
||||||
|
QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleRelative"),
|
||||||
|
QT_TRANSLATE_NOOP("Menu", "Toggle Relative Transforms"),
|
||||||
|
QT_TRANSLATE_NOOP("Status", "Toggle moving and rotating objects relative to the one that has focus"),
|
||||||
|
""
|
||||||
|
},
|
||||||
|
// LC_EDIT_TRANSFORM_SEPARATELY
|
||||||
|
{
|
||||||
|
QT_TRANSLATE_NOOP("Action", "Edit.TransformSeparately"),
|
||||||
|
QT_TRANSLATE_NOOP("Menu", "Rotate Separately"),
|
||||||
|
QT_TRANSLATE_NOOP("Status", "Rotate selected pieces separately"),
|
||||||
|
""
|
||||||
|
},
|
||||||
|
// LC_EDIT_TRANSFORM_TOGETHER
|
||||||
|
{
|
||||||
|
QT_TRANSLATE_NOOP("Action", "Edit.TransformTogether"),
|
||||||
|
QT_TRANSLATE_NOOP("Menu", "Rotate Together"),
|
||||||
|
QT_TRANSLATE_NOOP("Status", "Rotate selected pieces together"),
|
||||||
|
""
|
||||||
|
},
|
||||||
|
// LC_EDIT_TRANSFORM_TOGGLE_SEPARATE
|
||||||
|
{
|
||||||
|
QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleSeparate"),
|
||||||
|
QT_TRANSLATE_NOOP("Menu", "Toggle Separate Transforms"),
|
||||||
|
QT_TRANSLATE_NOOP("Status", "Toggle rotating selected pieces separately"),
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_EDIT_SNAP_MOVE_TOGGLE
|
// LC_EDIT_SNAP_MOVE_TOGGLE
|
||||||
|
@ -641,18 +641,32 @@ const lcCommand gCommands[] =
|
||||||
QT_TRANSLATE_NOOP("Status", "Add new pieces to the model"),
|
QT_TRANSLATE_NOOP("Status", "Add new pieces to the model"),
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_EDIT_ACTION_LIGHT
|
// LC_EDIT_ACTION_POINT_LIGHT
|
||||||
{
|
{
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.Tool.Light"),
|
QT_TRANSLATE_NOOP("Action", "Edit.Tool.PointLight"),
|
||||||
QT_TRANSLATE_NOOP("Menu", "Light"),
|
QT_TRANSLATE_NOOP("Menu", "Point Light"),
|
||||||
QT_TRANSLATE_NOOP("Status", "Add new omni light sources to the model"),
|
QT_TRANSLATE_NOOP("Status", "Add new point light sources to the model"),
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_EDIT_ACTION_SPOTLIGHT
|
// LC_EDIT_ACTION_SPOTLIGHT
|
||||||
{
|
{
|
||||||
QT_TRANSLATE_NOOP("Action", "Edit.Tool.Spotlight"),
|
QT_TRANSLATE_NOOP("Action", "Edit.Tool.SpotLight"),
|
||||||
QT_TRANSLATE_NOOP("Menu", "Spotlight"),
|
QT_TRANSLATE_NOOP("Menu", "Spot Light"),
|
||||||
QT_TRANSLATE_NOOP("Status", "Add new spotlights to the model"),
|
QT_TRANSLATE_NOOP("Status", "Add new spot lights to the model"),
|
||||||
|
""
|
||||||
|
},
|
||||||
|
// LC_EDIT_ACTION_DIRECTIONAL_LIGHT
|
||||||
|
{
|
||||||
|
QT_TRANSLATE_NOOP("Action", "Edit.Tool.DirectionalLight"),
|
||||||
|
QT_TRANSLATE_NOOP("Menu", "Directional Light"),
|
||||||
|
QT_TRANSLATE_NOOP("Status", "Add new omnidirectional light sources to the model"),
|
||||||
|
""
|
||||||
|
},
|
||||||
|
// LC_EDIT_ACTION_AREA_LIGHT
|
||||||
|
{
|
||||||
|
QT_TRANSLATE_NOOP("Action", "Edit.Tool.AreaLight"),
|
||||||
|
QT_TRANSLATE_NOOP("Menu", "Area Light"),
|
||||||
|
QT_TRANSLATE_NOOP("Status", "Add new area light sources to the model"),
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_EDIT_ACTION_CAMERA
|
// LC_EDIT_ACTION_CAMERA
|
||||||
|
@ -1362,7 +1376,7 @@ const lcCommand gCommands[] =
|
||||||
QT_TRANSLATE_NOOP("Status", "Make copies of the selected pieces"),
|
QT_TRANSLATE_NOOP("Status", "Make copies of the selected pieces"),
|
||||||
""
|
""
|
||||||
},
|
},
|
||||||
// LC_PIECE_VIEW_SELECTED_MODEL
|
// LC_PIECE_VIEW_SELECTED_MODEL
|
||||||
{
|
{
|
||||||
QT_TRANSLATE_NOOP("Action", "Piece.ViewSelectedModel"),
|
QT_TRANSLATE_NOOP("Action", "Piece.ViewSelectedModel"),
|
||||||
QT_TRANSLATE_NOOP("Menu", "Open Selected Model"),
|
QT_TRANSLATE_NOOP("Menu", "Open Selected Model"),
|
||||||
|
@ -1858,21 +1872,23 @@ LC_ARRAY_SIZE_CHECK(gCommands, LC_NUM_COMMANDS);
|
||||||
|
|
||||||
const char* gToolNames[] =
|
const char* gToolNames[] =
|
||||||
{
|
{
|
||||||
QT_TRANSLATE_NOOP("Mouse", "NewPiece"), // lcTool::Insert
|
QT_TRANSLATE_NOOP("Mouse", "NewPiece"), // lcTool::Insert
|
||||||
QT_TRANSLATE_NOOP("Mouse", "NewPointLight"), // lcTool::Light
|
QT_TRANSLATE_NOOP("Mouse", "NewPointLight"), // lcTool::PointLight
|
||||||
QT_TRANSLATE_NOOP("Mouse", "NewSpotLight"), // lcTool::SpotLight
|
QT_TRANSLATE_NOOP("Mouse", "NewSpotLight"), // lcTool::SpotLight
|
||||||
QT_TRANSLATE_NOOP("Mouse", "NewCamera"), // lcTool::Camera
|
QT_TRANSLATE_NOOP("Mouse", "NewDirectionalLight"), // lcTool::DirectionalLight
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Select"), // lcTool::Select
|
QT_TRANSLATE_NOOP("Mouse", "NewAreaLight"), // lcTool::AreaLight
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Move"), // lcTool::Move
|
QT_TRANSLATE_NOOP("Mouse", "NewCamera"), // lcTool::Camera
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Rotate"), // lcTool::Rotate
|
QT_TRANSLATE_NOOP("Mouse", "Select"), // lcTool::Select
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Delete"), // lcTool::Eraser
|
QT_TRANSLATE_NOOP("Mouse", "Move"), // lcTool::Move
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Paint"), // lcTool::Paint
|
QT_TRANSLATE_NOOP("Mouse", "Rotate"), // lcTool::Rotate
|
||||||
QT_TRANSLATE_NOOP("Mouse", "ColorPicker"), // lcTool::ColorPicker
|
QT_TRANSLATE_NOOP("Mouse", "Delete"), // lcTool::Eraser
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Zoom"), // lcTool::Zoom
|
QT_TRANSLATE_NOOP("Mouse", "Paint"), // lcTool::Paint
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Pan"), // lcTool::Pan
|
QT_TRANSLATE_NOOP("Mouse", "ColorPicker"), // lcTool::ColorPicker
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Orbit"), // lcTool::RotateView
|
QT_TRANSLATE_NOOP("Mouse", "Zoom"), // lcTool::Zoom
|
||||||
QT_TRANSLATE_NOOP("Mouse", "Roll"), // lcTool::Roll
|
QT_TRANSLATE_NOOP("Mouse", "Pan"), // lcTool::Pan
|
||||||
QT_TRANSLATE_NOOP("Mouse", "ZoomRegion") // lcTool::ZoomRegion
|
QT_TRANSLATE_NOOP("Mouse", "Orbit"), // lcTool::RotateView
|
||||||
|
QT_TRANSLATE_NOOP("Mouse", "Roll"), // lcTool::Roll
|
||||||
|
QT_TRANSLATE_NOOP("Mouse", "ZoomRegion") // lcTool::ZoomRegion
|
||||||
};
|
};
|
||||||
|
|
||||||
LC_ARRAY_SIZE_CHECK(gToolNames, lcTool::Count);
|
LC_ARRAY_SIZE_CHECK(gToolNames, lcTool::Count);
|
||||||
|
|
|
@ -98,8 +98,10 @@ enum lcCommandId
|
||||||
LC_EDIT_TRANSFORM_RELATIVE_ROTATION,
|
LC_EDIT_TRANSFORM_RELATIVE_ROTATION,
|
||||||
LC_EDIT_ACTION_FIRST,
|
LC_EDIT_ACTION_FIRST,
|
||||||
LC_EDIT_ACTION_INSERT = LC_EDIT_ACTION_FIRST,
|
LC_EDIT_ACTION_INSERT = LC_EDIT_ACTION_FIRST,
|
||||||
LC_EDIT_ACTION_LIGHT,
|
LC_EDIT_ACTION_POINT_LIGHT,
|
||||||
LC_EDIT_ACTION_SPOTLIGHT,
|
LC_EDIT_ACTION_SPOTLIGHT,
|
||||||
|
LC_EDIT_ACTION_DIRECTIONAL_LIGHT,
|
||||||
|
LC_EDIT_ACTION_AREA_LIGHT,
|
||||||
LC_EDIT_ACTION_CAMERA,
|
LC_EDIT_ACTION_CAMERA,
|
||||||
LC_EDIT_ACTION_SELECT,
|
LC_EDIT_ACTION_SELECT,
|
||||||
LC_EDIT_ACTION_MOVE,
|
LC_EDIT_ACTION_MOVE,
|
||||||
|
@ -298,8 +300,10 @@ extern const lcCommand gCommands[];
|
||||||
enum class lcTool
|
enum class lcTool
|
||||||
{
|
{
|
||||||
Insert,
|
Insert,
|
||||||
Light,
|
PointLight,
|
||||||
SpotLight,
|
SpotLight,
|
||||||
|
DirectionalLight,
|
||||||
|
AreaLight,
|
||||||
Camera,
|
Camera,
|
||||||
Select,
|
Select,
|
||||||
Move,
|
Move,
|
||||||
|
|
|
@ -75,6 +75,8 @@ class lcObject;
|
||||||
class lcPiece;
|
class lcPiece;
|
||||||
class lcCamera;
|
class lcCamera;
|
||||||
class lcLight;
|
class lcLight;
|
||||||
|
enum class lcLightType;
|
||||||
|
enum class lcLightAreaShape;
|
||||||
class lcGroup;
|
class lcGroup;
|
||||||
class PieceInfo;
|
class PieceInfo;
|
||||||
typedef std::map<const PieceInfo*, std::map<int, int>> lcPartsList;
|
typedef std::map<const PieceInfo*, std::map<int, int>> lcPartsList;
|
||||||
|
|
|
@ -204,13 +204,23 @@ void lcMainWindow::CreateActions()
|
||||||
QIcon EditActionLightIcon;
|
QIcon EditActionLightIcon;
|
||||||
EditActionLightIcon.addFile(":/resources/action_light.png");
|
EditActionLightIcon.addFile(":/resources/action_light.png");
|
||||||
EditActionLightIcon.addFile(":/resources/action_light_16.png");
|
EditActionLightIcon.addFile(":/resources/action_light_16.png");
|
||||||
mActions[LC_EDIT_ACTION_LIGHT]->setIcon(EditActionLightIcon);
|
mActions[LC_EDIT_ACTION_POINT_LIGHT]->setIcon(EditActionLightIcon);
|
||||||
|
|
||||||
QIcon EditActionSpotLightIcon;
|
QIcon EditActionSpotLightIcon;
|
||||||
EditActionSpotLightIcon.addFile(":/resources/action_spotlight.png");
|
EditActionSpotLightIcon.addFile(":/resources/action_spotlight.png");
|
||||||
EditActionSpotLightIcon.addFile(":/resources/action_spotlight_16.png");
|
EditActionSpotLightIcon.addFile(":/resources/action_spotlight_16.png");
|
||||||
mActions[LC_EDIT_ACTION_SPOTLIGHT]->setIcon(EditActionSpotLightIcon);
|
mActions[LC_EDIT_ACTION_SPOTLIGHT]->setIcon(EditActionSpotLightIcon);
|
||||||
|
|
||||||
|
QIcon EditActionSunlightIcon;
|
||||||
|
EditActionSunlightIcon.addFile(":/resources/action_sunlight.png");
|
||||||
|
EditActionSunlightIcon.addFile(":/resources/action_sunlight_16.png");
|
||||||
|
mActions[LC_EDIT_ACTION_DIRECTIONAL_LIGHT]->setIcon(EditActionSunlightIcon);
|
||||||
|
|
||||||
|
QIcon EditActionArealightIcon;
|
||||||
|
EditActionArealightIcon.addFile(":/resources/action_arealight.png");
|
||||||
|
EditActionArealightIcon.addFile(":/resources/action_arealight_16.png");
|
||||||
|
mActions[LC_EDIT_ACTION_AREA_LIGHT]->setIcon(EditActionArealightIcon);
|
||||||
|
|
||||||
QIcon EditActionSelectIcon;
|
QIcon EditActionSelectIcon;
|
||||||
EditActionSelectIcon.addFile(":/resources/action_select.png");
|
EditActionSelectIcon.addFile(":/resources/action_select.png");
|
||||||
EditActionSelectIcon.addFile(":/resources/action_select_16.png");
|
EditActionSelectIcon.addFile(":/resources/action_select_16.png");
|
||||||
|
@ -421,8 +431,10 @@ void lcMainWindow::CreateMenus()
|
||||||
|
|
||||||
mToolsMenu = new QMenu(tr("Tools"), this);
|
mToolsMenu = new QMenu(tr("Tools"), this);
|
||||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_INSERT]);
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_INSERT]);
|
||||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_LIGHT]);
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_POINT_LIGHT]);
|
||||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]);
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]);
|
||||||
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_DIRECTIONAL_LIGHT]);
|
||||||
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_AREA_LIGHT]);
|
||||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
|
||||||
mToolsMenu->addSeparator();
|
mToolsMenu->addSeparator();
|
||||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SELECT]);
|
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SELECT]);
|
||||||
|
@ -664,8 +676,10 @@ void lcMainWindow::CreateToolBars()
|
||||||
mToolsToolBar->setObjectName("ToolsToolbar");
|
mToolsToolBar->setObjectName("ToolsToolbar");
|
||||||
insertToolBarBreak(mToolsToolBar);
|
insertToolBarBreak(mToolsToolBar);
|
||||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_INSERT]);
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_INSERT]);
|
||||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_LIGHT]);
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_POINT_LIGHT]);
|
||||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]);
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SPOTLIGHT]);
|
||||||
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_DIRECTIONAL_LIGHT]);
|
||||||
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_AREA_LIGHT]);
|
||||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
|
||||||
mToolsToolBar->addSeparator();
|
mToolsToolBar->addSeparator();
|
||||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SELECT]);
|
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SELECT]);
|
||||||
|
@ -817,7 +831,7 @@ void lcMainWindow::TogglePreviewWidget(bool Visible)
|
||||||
else
|
else
|
||||||
mPreviewToolBar->hide();
|
mPreviewToolBar->hide();
|
||||||
}
|
}
|
||||||
else if (Visible)
|
else if (Visible)
|
||||||
{
|
{
|
||||||
CreatePreviewWidget();
|
CreatePreviewWidget();
|
||||||
}
|
}
|
||||||
|
@ -2887,62 +2901,62 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
|
||||||
|
|
||||||
case LC_PIECE_MOVE_PLUSX:
|
case LC_PIECE_MOVE_PLUSX:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true);
|
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_MOVE_MINUSX:
|
case LC_PIECE_MOVE_MINUSX:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(-lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true);
|
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(-lcMax(GetMoveXYSnap(), 0.1f), 0.0f, 0.0f)), true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_MOVE_PLUSY:
|
case LC_PIECE_MOVE_PLUSY:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true);
|
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_MOVE_MINUSY:
|
case LC_PIECE_MOVE_MINUSY:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true);
|
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetMoveXYSnap(), 0.1f), 0.0f)), true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_MOVE_PLUSZ:
|
case LC_PIECE_MOVE_PLUSZ:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true);
|
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_MOVE_MINUSZ:
|
case LC_PIECE_MOVE_MINUSZ:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true);
|
ActiveModel->MoveSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetMoveZSnap(), 0.1f))), true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_ROTATE_PLUSX:
|
case LC_PIECE_ROTATE_PLUSX:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
|
ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_ROTATE_MINUSX:
|
case LC_PIECE_ROTATE_MINUSX:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
|
ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(-lcVector3(lcMax(GetAngleSnap(), 1.0f), 0.0f, 0.0f)), true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_ROTATE_PLUSY:
|
case LC_PIECE_ROTATE_PLUSY:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
|
ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_ROTATE_MINUSY:
|
case LC_PIECE_ROTATE_MINUSY:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
|
ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, -lcMax(GetAngleSnap(), 1.0f), 0.0f)), true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_ROTATE_PLUSZ:
|
case LC_PIECE_ROTATE_PLUSZ:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
|
ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_ROTATE_MINUSZ:
|
case LC_PIECE_ROTATE_MINUSZ:
|
||||||
if (ActiveModel)
|
if (ActiveModel)
|
||||||
ActiveModel->RotateSelectedPieces(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
|
ActiveModel->RotateSelectedObjects(ActiveView->GetMoveDirection(lcVector3(0.0f, 0.0f, -lcMax(GetAngleSnap(), 1.0f))), true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_PIECE_MINIFIG_WIZARD:
|
case LC_PIECE_MINIFIG_WIZARD:
|
||||||
|
@ -3362,8 +3376,16 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
|
||||||
SetTool(lcTool::Insert);
|
SetTool(lcTool::Insert);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_EDIT_ACTION_LIGHT:
|
case LC_EDIT_ACTION_POINT_LIGHT:
|
||||||
SetTool(lcTool::Light);
|
SetTool(lcTool::PointLight);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LC_EDIT_ACTION_AREA_LIGHT:
|
||||||
|
SetTool(lcTool::AreaLight);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LC_EDIT_ACTION_DIRECTIONAL_LIGHT:
|
||||||
|
SetTool(lcTool::DirectionalLight);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LC_EDIT_ACTION_SPOTLIGHT:
|
case LC_EDIT_ACTION_SPOTLIGHT:
|
||||||
|
|
144
common/lc_math.h
144
common/lc_math.h
|
@ -51,6 +51,21 @@ inline T lcClamp(const T& Value, const T& Min, const T& Max)
|
||||||
return Value;
|
return Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class lcVector2i
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcVector2i()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr lcVector2i(const int _x, const int _y)
|
||||||
|
: x(_x), y(_y)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
|
||||||
class lcVector2
|
class lcVector2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -649,6 +664,11 @@ inline lcVector3 lcVector3FromColor(quint32 Color)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline lcVector3 lcVector3FromQColor(QColor Color)
|
||||||
|
{
|
||||||
|
return lcVector3(Color.redF(), Color.greenF(), Color.blueF());
|
||||||
|
}
|
||||||
|
|
||||||
inline lcVector4 lcVector4FromColor(quint32 Color)
|
inline lcVector4 lcVector4FromColor(quint32 Color)
|
||||||
{
|
{
|
||||||
lcVector4 v(LC_RGBA_RED(Color), LC_RGBA_GREEN(Color), LC_RGBA_BLUE(Color), LC_RGBA_ALPHA(Color));
|
lcVector4 v(LC_RGBA_RED(Color), LC_RGBA_GREEN(Color), LC_RGBA_BLUE(Color), LC_RGBA_ALPHA(Color));
|
||||||
|
@ -661,6 +681,11 @@ inline quint32 lcColorFromVector3(const lcVector3& Color)
|
||||||
return LC_RGB(roundf(Color[0] * 255), roundf(Color[1] * 255), roundf(Color[2] * 255));
|
return LC_RGB(roundf(Color[0] * 255), roundf(Color[1] * 255), roundf(Color[2] * 255));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QColor lcQColorFromVector3(const lcVector3& Color)
|
||||||
|
{
|
||||||
|
return QColor::fromRgb(roundf(Color[0] * 255), roundf(Color[1] * 255), roundf(Color[2] * 255));
|
||||||
|
}
|
||||||
|
|
||||||
inline float lcLuminescence(const lcVector3& Color)
|
inline float lcLuminescence(const lcVector3& Color)
|
||||||
{
|
{
|
||||||
return 0.2126f * Color[0] + 0.7152f * Color[1] + 0.0722f * Color[2];
|
return 0.2126f * Color[0] + 0.7152f * Color[1] + 0.0722f * Color[2];
|
||||||
|
@ -1991,6 +2016,125 @@ inline bool lcSphereRayMinIntersectDistance(const lcVector3& Center, float Radiu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool lcConeRayMinIntersectDistance(const lcVector3& Tip, const lcVector3& Direction, float Radius, float Height, const lcVector3& Start, const lcVector3& End, float* Dist)
|
||||||
|
{
|
||||||
|
const lcVector3 v = End - Start;
|
||||||
|
const lcVector3 h = Direction;
|
||||||
|
const lcVector3 w = Start - Tip;
|
||||||
|
const float vh = lcDot(v, h);
|
||||||
|
const float wh = lcDot(w, h);
|
||||||
|
const float m = (Radius * Radius) / (Height * Height);
|
||||||
|
|
||||||
|
const float a = lcDot(v, v) - m * vh * vh - vh * vh;
|
||||||
|
const float b = 2 * (lcDot(v, w) - m * vh * wh - vh * wh);
|
||||||
|
const float c = lcDot(w, w) - m * wh * wh - wh * wh;
|
||||||
|
|
||||||
|
const float delta = b * b - 4 * a * c;
|
||||||
|
|
||||||
|
if (delta < 0.0f)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float ts[2] = { (-b - sqrtf(delta)) / (2 * a), (-b + sqrtf(delta)) / (2 * a) };
|
||||||
|
|
||||||
|
for (int ti = 0; ti < 2; ti++)
|
||||||
|
{
|
||||||
|
float t = ts[ti];
|
||||||
|
lcVector3 Intersection = Start + v * t;
|
||||||
|
|
||||||
|
float ConeD = lcDot(Intersection - Tip, Direction);
|
||||||
|
|
||||||
|
if (ConeD < 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ConeD < Height)
|
||||||
|
{
|
||||||
|
*Dist = lcLength(Intersection - Start);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector3 Center(Tip + Direction * Height);
|
||||||
|
lcVector4 Plane(Direction, -lcDot(Direction, Center));
|
||||||
|
|
||||||
|
if (lcLineSegmentPlaneIntersection(&Intersection, Start, End, Plane))
|
||||||
|
{
|
||||||
|
if (lcLengthSquared(Center - Intersection) < Radius * Radius)
|
||||||
|
{
|
||||||
|
*Dist = lcLength(Intersection - Start);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool lcCylinderRayMinIntersectDistance(float Radius, float Height, const lcVector3& Start, const lcVector3& End, float* Dist)
|
||||||
|
{
|
||||||
|
lcVector4 BottomPlane(0.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
lcVector3 Intersection;
|
||||||
|
float MinDistance = FLT_MAX;
|
||||||
|
|
||||||
|
if (lcLineSegmentPlaneIntersection(&Intersection, Start, End, BottomPlane))
|
||||||
|
{
|
||||||
|
if (Intersection.x * Intersection.x + Intersection.y * Intersection.y < Radius * Radius)
|
||||||
|
{
|
||||||
|
float Distance = lcLength(Intersection - Start);
|
||||||
|
|
||||||
|
if (Distance < MinDistance)
|
||||||
|
MinDistance = Distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector4 TopPlane(0.0f, 0.0f, 1.0f, -Height);
|
||||||
|
|
||||||
|
if (lcLineSegmentPlaneIntersection(&Intersection, Start, End, TopPlane))
|
||||||
|
{
|
||||||
|
if (Intersection.x * Intersection.x + Intersection.y * Intersection.y < Radius * Radius)
|
||||||
|
{
|
||||||
|
float Distance = lcLength(Intersection - Start);
|
||||||
|
|
||||||
|
if (Distance < MinDistance)
|
||||||
|
MinDistance = Distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector3 Direction = End - Start;
|
||||||
|
|
||||||
|
float a = (Direction.x * Direction.x) + (Direction.y * Direction.y);
|
||||||
|
float b = 2 * (Direction.x * Start.x + Direction.y * Start.y);
|
||||||
|
float c = (Start.x * Start.x) + (Start.y * Start.y) - (Radius * Radius);
|
||||||
|
|
||||||
|
float delta = b * b - 4 * (a * c);
|
||||||
|
|
||||||
|
if (delta > 0.0f)
|
||||||
|
{
|
||||||
|
float ts[2] = { (-b - sqrtf(delta)) / (2 * a), (-b + sqrtf(delta)) / (2 * a) };
|
||||||
|
|
||||||
|
for (int ti = 0; ti < 2; ti++)
|
||||||
|
{
|
||||||
|
float t = ts[ti];
|
||||||
|
Intersection = Start + Direction * t;
|
||||||
|
|
||||||
|
if (Intersection.z < 0.0f || Intersection.z > Height)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float Distance = lcLength(Intersection - Start);
|
||||||
|
|
||||||
|
if (Distance < MinDistance)
|
||||||
|
MinDistance = Distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MinDistance == FLT_MAX)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*Dist = MinDistance;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline lcVector3 lcRayPointClosestPoint(const lcVector3& Point, const lcVector3& Start, const lcVector3& End)
|
inline lcVector3 lcRayPointClosestPoint(const lcVector3& Point, const lcVector3& Start, const lcVector3& End)
|
||||||
{
|
{
|
||||||
const lcVector3 Dir = Point - Start;
|
const lcVector3 Dir = Point - Start;
|
||||||
|
|
|
@ -305,14 +305,14 @@ void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char** Color
|
||||||
const lcVector3 n2 = lcUnpackNormal(Verts[Indices[Idx + 1]].Normal);
|
const lcVector3 n2 = lcUnpackNormal(Verts[Indices[Idx + 1]].Normal);
|
||||||
const lcVector3 n3 = lcUnpackNormal(Verts[Indices[Idx + 2]].Normal);
|
const lcVector3 n3 = lcUnpackNormal(Verts[Indices[Idx + 2]].Normal);
|
||||||
|
|
||||||
sprintf(Line, " smooth_triangle { <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f>, <%.2f, %.2f, %.2f> }\n",
|
sprintf(Line, " smooth_triangle { <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g> }\n",
|
||||||
-v1.y, -v1.x, v1.z, -n1.y, -n1.x, n1.z, -v2.y, -v2.x, v2.z, -n2.y, -n2.x, n2.z, -v3.y, -v3.x, v3.z, -n3.y, -n3.x, n3.z);
|
-v1.y, -v1.x, v1.z, -n1.y, -n1.x, n1.z, -v2.y, -v2.x, v2.z, -n2.y, -n2.x, n2.z, -v3.y, -v3.x, v3.z, -n3.y, -n3.x, n3.z);
|
||||||
File.WriteLine(Line);
|
File.WriteLine(Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Section->ColorIndex != gDefaultColor)
|
if (Section->ColorIndex != gDefaultColor)
|
||||||
{
|
{
|
||||||
sprintf(Line, "material { texture { %s normal { bumps 0.1 scale 2 } } }", ColorTable[Section->ColorIndex]);
|
sprintf(Line, " material { texture { %s normal { bumps 0.1 scale 2 } } }", ColorTable[Section->ColorIndex]);
|
||||||
File.WriteLine(Line);
|
File.WriteLine(Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,86 @@ void lcModelProperties::ParseLDrawLine(QTextStream& Stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lcPOVRayOptions::lcPOVRayOptions() :
|
||||||
|
UseLGEO(false),
|
||||||
|
ExcludeFloor(false),
|
||||||
|
ExcludeBackground(false),
|
||||||
|
NoReflection(false),
|
||||||
|
NoShadow(false),
|
||||||
|
FloorAxis(1),
|
||||||
|
FloorAmbient(0.4f),
|
||||||
|
FloorDiffuse(0.4f),
|
||||||
|
FloorColor(0.8f,0.8f,0.8f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void lcPOVRayOptions::ParseLDrawLine(QTextStream& LineStream)
|
||||||
|
{
|
||||||
|
QString Token;
|
||||||
|
LineStream >> Token;
|
||||||
|
|
||||||
|
if (Token == QLatin1String("HEADER_INCLUDE_FILE"))
|
||||||
|
{
|
||||||
|
LineStream >> HeaderIncludeFile;
|
||||||
|
if (!QFileInfo(HeaderIncludeFile).isReadable())
|
||||||
|
HeaderIncludeFile.clear();
|
||||||
|
}
|
||||||
|
else if (Token == QLatin1String("FOOTER_INCLUDE_FILE"))
|
||||||
|
{
|
||||||
|
LineStream >> FooterIncludeFile;
|
||||||
|
if (!QFileInfo(FooterIncludeFile).isReadable())
|
||||||
|
FooterIncludeFile.clear();
|
||||||
|
}
|
||||||
|
else if (Token == QLatin1String("FLOOR_AXIS"))
|
||||||
|
{
|
||||||
|
LineStream >> FloorAxis;
|
||||||
|
if (FloorAxis < 0 || FloorAxis > 2)
|
||||||
|
FloorAxis = 1; // y
|
||||||
|
}
|
||||||
|
else if (Token == QLatin1String("FLOOR_COLOR_RGB"))
|
||||||
|
LineStream >> FloorColor[0] >> FloorColor[1] >> FloorColor[2];
|
||||||
|
else if (Token == QLatin1String("FLOOR_AMBIENT"))
|
||||||
|
LineStream >> FloorAmbient;
|
||||||
|
else if (Token == QLatin1String("FLOOR_DIFFUSE"))
|
||||||
|
LineStream >> FloorDiffuse;
|
||||||
|
else if (Token == QLatin1String("EXCLUDE_FLOOR"))
|
||||||
|
ExcludeFloor = true;
|
||||||
|
else if (Token == QLatin1String("EXCLUDE_BACKGROUND"))
|
||||||
|
ExcludeFloor = true;
|
||||||
|
else if (Token == QLatin1String("NO_REFLECTION"))
|
||||||
|
NoReflection = true;
|
||||||
|
else if (Token == QLatin1String("NO_SHADOWS"))
|
||||||
|
NoShadow = true;
|
||||||
|
else if (Token == QLatin1String("USE_LGEO"))
|
||||||
|
UseLGEO = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcPOVRayOptions::SaveLDraw(QTextStream& Stream) const
|
||||||
|
{
|
||||||
|
const QLatin1String LineEnding("\r\n");
|
||||||
|
if (!HeaderIncludeFile.isEmpty())
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY HEADER_INCLUDE_FILE ") << QDir::toNativeSeparators(HeaderIncludeFile) << LineEnding;
|
||||||
|
if (!FooterIncludeFile.isEmpty())
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY FOOTER_INCLUDE_FILE ") << QDir::toNativeSeparators(FooterIncludeFile) << LineEnding;
|
||||||
|
if (FloorAxis != 1)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY FLOOR_AXIS ") << FloorAxis << LineEnding;
|
||||||
|
if (FloorColor != lcVector3(0.8f,0.8f,0.8f))
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY FLOOR_COLOR_RGB ") << FloorColor[0] << ' ' << FloorColor[1] << ' ' << FloorColor[2] << LineEnding;
|
||||||
|
if (FloorAmbient != 0.4f)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY FLOOR_AMBIENT ") << FloorAmbient << LineEnding;
|
||||||
|
if (FloorDiffuse != 0.4f)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY FLOOR_DIFFUSE ") << FloorDiffuse << LineEnding;
|
||||||
|
if (ExcludeFloor)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY EXCLUDE_FLOOR") << LineEnding;
|
||||||
|
if (ExcludeBackground)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY EXCLUDE_BACKGROUND") << LineEnding;
|
||||||
|
if (NoReflection)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY NO_REFLECTION") << LineEnding;
|
||||||
|
if (NoShadow)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY NO_SHADOWS") << LineEnding;
|
||||||
|
if (UseLGEO)
|
||||||
|
Stream << QLatin1String("0 !LEOCAD POV_RAY USE_LGEO") << LineEnding;
|
||||||
|
}
|
||||||
|
|
||||||
lcModel::lcModel(const QString& FileName, Project* Project, bool Preview)
|
lcModel::lcModel(const QString& FileName, Project* Project, bool Preview)
|
||||||
: mProject(Project), mIsPreview(Preview)
|
: mProject(Project), mIsPreview(Preview)
|
||||||
{
|
{
|
||||||
|
@ -540,7 +620,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||||
|
|
||||||
if (Token != QLatin1String("!LEOCAD"))
|
if (Token != QLatin1String("!LEOCAD"))
|
||||||
{
|
{
|
||||||
mFileLines.append(OriginalLine);
|
mFileLines.append(OriginalLine);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,6 +651,19 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||||
}
|
}
|
||||||
else if (Token == QLatin1String("LIGHT"))
|
else if (Token == QLatin1String("LIGHT"))
|
||||||
{
|
{
|
||||||
|
if (!Light)
|
||||||
|
Light = new lcLight(lcVector3(0.0f, 0.0f, 0.0f), lcLightType::Point);
|
||||||
|
|
||||||
|
if (Light->ParseLDrawLine(LineStream))
|
||||||
|
{
|
||||||
|
Light->CreateName(mLights);
|
||||||
|
mLights.Add(Light);
|
||||||
|
Light = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Token == QLatin1String("POV_RAY"))
|
||||||
|
{
|
||||||
|
mPOVRayOptions.ParseLDrawLine(LineStream);
|
||||||
}
|
}
|
||||||
else if (Token == QLatin1String("GROUP"))
|
else if (Token == QLatin1String("GROUP"))
|
||||||
{
|
{
|
||||||
|
@ -641,7 +734,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
||||||
|
|
||||||
if (Library->IsPrimitive(CleanId.constData()))
|
if (Library->IsPrimitive(CleanId.constData()))
|
||||||
{
|
{
|
||||||
mFileLines.append(OriginalLine);
|
mFileLines.append(OriginalLine);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -946,7 +1039,7 @@ bool lcModel::LoadLDD(const QString& FileData)
|
||||||
{
|
{
|
||||||
std::vector<lcPiece*> Pieces;
|
std::vector<lcPiece*> Pieces;
|
||||||
std::vector<std::vector<lcPiece*>> Groups;
|
std::vector<std::vector<lcPiece*>> Groups;
|
||||||
|
|
||||||
if (!lcImportLXFMLFile(FileData, Pieces, Groups))
|
if (!lcImportLXFMLFile(FileData, Pieces, Groups))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2131,8 +2224,14 @@ lcMatrix33 lcModel::GetRelativeRotation() const
|
||||||
{
|
{
|
||||||
const lcObject* Focus = GetFocusObject();
|
const lcObject* Focus = GetFocusObject();
|
||||||
|
|
||||||
if (Focus && Focus->IsPiece())
|
if (Focus)
|
||||||
return ((lcPiece*)Focus)->GetRelativeRotation();
|
{
|
||||||
|
if (Focus->IsPiece())
|
||||||
|
return ((lcPiece*)Focus)->GetRelativeRotation();
|
||||||
|
|
||||||
|
if (Focus->IsLight())
|
||||||
|
return ((lcLight*)Focus)->GetRelativeRotation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lcMatrix33Identity();
|
return lcMatrix33Identity();
|
||||||
|
@ -2606,7 +2705,7 @@ bool lcModel::RemoveSelectedObjects()
|
||||||
return RemovedPiece || RemovedCamera || RemovedLight;
|
return RemovedPiece || RemovedCamera || RemovedLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint)
|
void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove)
|
||||||
{
|
{
|
||||||
bool Moved = false;
|
bool Moved = false;
|
||||||
lcMatrix33 RelativeRotation;
|
lcMatrix33 RelativeRotation;
|
||||||
|
@ -2667,7 +2766,7 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
|
||||||
{
|
{
|
||||||
if (Light->IsSelected())
|
if (Light->IsSelected())
|
||||||
{
|
{
|
||||||
Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance);
|
Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance, FirstMove);
|
||||||
Light->UpdatePosition(mCurrentStep);
|
Light->UpdatePosition(mCurrentStep);
|
||||||
Moved = true;
|
Moved = true;
|
||||||
}
|
}
|
||||||
|
@ -2677,13 +2776,15 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
|
||||||
if (Moved && Update)
|
if (Moved && Update)
|
||||||
{
|
{
|
||||||
UpdateAllViews();
|
UpdateAllViews();
|
||||||
|
|
||||||
if (Checkpoint)
|
if (Checkpoint)
|
||||||
SaveCheckpoint(tr("Moving"));
|
SaveCheckpoint(tr("Moving"));
|
||||||
|
|
||||||
gMainWindow->UpdateSelectedObjects(false);
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint)
|
void lcModel::RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint)
|
||||||
{
|
{
|
||||||
if (Angles.LengthSquared() < 0.001f)
|
if (Angles.LengthSquared() < 0.001f)
|
||||||
return;
|
return;
|
||||||
|
@ -2712,6 +2813,12 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int Flags;
|
||||||
|
lcArray<lcObject*> Selection;
|
||||||
|
lcObject* Focus;
|
||||||
|
|
||||||
|
GetSelectionInformation(&Flags, Selection, &Focus);
|
||||||
|
|
||||||
if (!gMainWindow->GetSeparateTransform())
|
if (!gMainWindow->GetSeparateTransform())
|
||||||
{
|
{
|
||||||
lcVector3 Center;
|
lcVector3 Center;
|
||||||
|
@ -2729,42 +2836,78 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
|
||||||
else
|
else
|
||||||
WorldToFocusMatrix = lcMatrix33Identity();
|
WorldToFocusMatrix = lcMatrix33Identity();
|
||||||
|
|
||||||
for (lcPiece* Piece : mPieces)
|
for (lcObject* Object : Selection)
|
||||||
{
|
{
|
||||||
if (!Piece->IsSelected())
|
if (Object->IsPiece())
|
||||||
continue;
|
{
|
||||||
|
lcPiece* Piece = (lcPiece*)Object;
|
||||||
|
|
||||||
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
||||||
Piece->UpdatePosition(mCurrentStep);
|
Piece->UpdatePosition(mCurrentStep);
|
||||||
Rotated = true;
|
Rotated = true;
|
||||||
|
}
|
||||||
|
else if (Object->IsLight())
|
||||||
|
{
|
||||||
|
lcLight* Light = (lcLight*)Object;
|
||||||
|
|
||||||
|
Light->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
Rotated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (lcPiece* Piece : mPieces)
|
for (lcObject* Object : Selection)
|
||||||
{
|
{
|
||||||
if (!Piece->IsSelected())
|
if (Object->IsPiece())
|
||||||
continue;
|
|
||||||
|
|
||||||
const lcVector3 Center = Piece->GetRotationCenter();
|
|
||||||
lcMatrix33 WorldToFocusMatrix;
|
|
||||||
lcMatrix33 RelativeRotationMatrix;
|
|
||||||
|
|
||||||
if (Relative)
|
|
||||||
{
|
{
|
||||||
const lcMatrix33 RelativeRotation = Piece->GetRelativeRotation();
|
lcPiece* Piece = (lcPiece*)Object;
|
||||||
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
|
|
||||||
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WorldToFocusMatrix = lcMatrix33Identity();
|
|
||||||
RelativeRotationMatrix = RotationMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix);
|
const lcVector3 Center = Piece->GetRotationCenter();
|
||||||
Piece->UpdatePosition(mCurrentStep);
|
lcMatrix33 WorldToFocusMatrix;
|
||||||
Rotated = true;
|
lcMatrix33 RelativeRotationMatrix;
|
||||||
|
|
||||||
|
if (Relative)
|
||||||
|
{
|
||||||
|
const lcMatrix33 RelativeRotation = Piece->GetRelativeRotation();
|
||||||
|
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
|
||||||
|
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorldToFocusMatrix = lcMatrix33Identity();
|
||||||
|
RelativeRotationMatrix = RotationMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix);
|
||||||
|
Piece->UpdatePosition(mCurrentStep);
|
||||||
|
Rotated = true;
|
||||||
|
}
|
||||||
|
else if (Object->IsLight())
|
||||||
|
{
|
||||||
|
lcLight* Light = (lcLight*)Object;
|
||||||
|
|
||||||
|
const lcVector3 Center = Light->GetRotationCenter();
|
||||||
|
lcMatrix33 WorldToFocusMatrix;
|
||||||
|
lcMatrix33 RelativeRotationMatrix;
|
||||||
|
|
||||||
|
if (Relative)
|
||||||
|
{
|
||||||
|
const lcMatrix33 RelativeRotation = Light->GetRelativeRotation();
|
||||||
|
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
|
||||||
|
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WorldToFocusMatrix = lcMatrix33Identity();
|
||||||
|
RelativeRotationMatrix = RotationMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
Light->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
Rotated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2810,19 +2953,19 @@ void lcModel::TransformSelectedObjects(lcTransformType TransformType, const lcVe
|
||||||
switch (TransformType)
|
switch (TransformType)
|
||||||
{
|
{
|
||||||
case lcTransformType::AbsoluteTranslation:
|
case lcTransformType::AbsoluteTranslation:
|
||||||
MoveSelectedObjects(Transform, false, false, true, true);
|
MoveSelectedObjects(Transform, false, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTransformType::RelativeTranslation:
|
case lcTransformType::RelativeTranslation:
|
||||||
MoveSelectedObjects(Transform, true, false, true, true);
|
MoveSelectedObjects(Transform, true, false, true, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTransformType::AbsoluteRotation:
|
case lcTransformType::AbsoluteRotation:
|
||||||
RotateSelectedPieces(Transform, false, false, true, true);
|
RotateSelectedObjects(Transform, false, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTransformType::RelativeRotation:
|
case lcTransformType::RelativeRotation:
|
||||||
RotateSelectedPieces(Transform, true, false, true, true);
|
RotateSelectedObjects(Transform, true, false, true, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTransformType::Count:
|
case lcTransformType::Count:
|
||||||
|
@ -3011,6 +3154,147 @@ void lcModel::SetCameraName(lcCamera* Camera, const QString& Name)
|
||||||
gMainWindow->UpdateCameraMenu();
|
gMainWindow->UpdateCameraMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightType(lcLight* Light, lcLightType LightType)
|
||||||
|
{
|
||||||
|
if (!Light->SetLightType(LightType))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Type"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightColor(lcLight* Light, const lcVector3& Color)
|
||||||
|
{
|
||||||
|
Light->SetColor(Color, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Color"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightAttenuationDistance(lcLight* Light, float Distance)
|
||||||
|
{
|
||||||
|
Light->SetAttenuationDistance(Distance, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Attenuation Distance"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightAttenuationPower(lcLight* Light, float Power)
|
||||||
|
{
|
||||||
|
Light->SetAttenuationPower(Power, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Attenuation Power"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetSpotLightConeAngle(lcLight* Light, float Angle)
|
||||||
|
{
|
||||||
|
Light->SetSpotConeAngle(Angle, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Spot Light Cone Angle"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetSpotLightPenumbraAngle(lcLight* Light, float Angle)
|
||||||
|
{
|
||||||
|
Light->SetSpotPenumbraAngle(Angle, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Spot Light Penumbra Angle"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetSpotLightTightness(lcLight* Light, float Tightness)
|
||||||
|
{
|
||||||
|
Light->SetSpotTightness(Tightness, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Spot Light Tightness"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightAreaShape(lcLight* Light, lcLightAreaShape LightAreaShape)
|
||||||
|
{
|
||||||
|
if (!Light->SetAreaShape(LightAreaShape))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Area Light Shape"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightAreaGrid(lcLight* Light, lcVector2i AreaGrid)
|
||||||
|
{
|
||||||
|
if (!Light->SetAreaGrid(AreaGrid, mCurrentStep, gMainWindow->GetAddKeys()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Area Light Size"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightSize(lcLight* Light, lcVector2 LightAreaSize)
|
||||||
|
{
|
||||||
|
Light->SetSize(LightAreaSize, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Size"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightPower(lcLight* Light, float Power)
|
||||||
|
{
|
||||||
|
Light->SetPower(Power, mCurrentStep, gMainWindow->GetAddKeys());
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Power"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightCastShadow(lcLight* Light, bool CastShadow)
|
||||||
|
{
|
||||||
|
if (!Light->SetCastShadow(CastShadow))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Light->UpdatePosition(mCurrentStep);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Changing Light Shadow"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcModel::SetLightName(lcLight* Light, const QString &Name)
|
||||||
|
{
|
||||||
|
if (Light->GetName() == Name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Light->SetName(Name);
|
||||||
|
|
||||||
|
SaveCheckpoint(tr("Renaming Light"));
|
||||||
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
|
UpdateAllViews();
|
||||||
|
gMainWindow->UpdateCameraMenu();
|
||||||
|
}
|
||||||
|
|
||||||
bool lcModel::AnyPiecesSelected() const
|
bool lcModel::AnyPiecesSelected() const
|
||||||
{
|
{
|
||||||
for (const lcPiece* Piece : mPieces)
|
for (const lcPiece* Piece : mPieces)
|
||||||
|
@ -3123,20 +3407,18 @@ bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRota
|
||||||
if (!Light->IsSelected())
|
if (!Light->IsSelected())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (Light->IsFocused() && Relative)
|
if (Light->IsFocused())
|
||||||
{
|
{
|
||||||
Center = Light->GetSectionPosition(Light->GetFocusSection());
|
Center = Light->GetRotationCenter();
|
||||||
// RelativeRotation = Piece->GetRelativeRotation();
|
|
||||||
|
if (Relative)
|
||||||
|
RelativeRotation = Light->GetRelativeRotation();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION);
|
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION);
|
||||||
NumSelected++;
|
NumSelected++;
|
||||||
if (Light->IsSpotLight() || Light->IsDirectionalLight())
|
|
||||||
{
|
|
||||||
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_TARGET);
|
|
||||||
NumSelected++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NumSelected)
|
if (NumSelected)
|
||||||
|
@ -3148,6 +3430,33 @@ bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRota
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lcModel::CanRotateSelection() const
|
||||||
|
{
|
||||||
|
int Flags;
|
||||||
|
lcArray<lcObject*> Selection;
|
||||||
|
lcObject* Focus;
|
||||||
|
|
||||||
|
GetSelectionInformation(&Flags, Selection, &Focus);
|
||||||
|
|
||||||
|
if (Flags & LC_SEL_PIECE)
|
||||||
|
{
|
||||||
|
if ((Flags & (LC_SEL_CAMERA | LC_SEL_LIGHT)) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Flags & (LC_SEL_PIECE | LC_SEL_CAMERA)) == 0)
|
||||||
|
{
|
||||||
|
if (Focus && Focus->IsLight())
|
||||||
|
{
|
||||||
|
lcLight* Light = (lcLight*)Focus;
|
||||||
|
|
||||||
|
return (Light->GetAllowedTransforms() & LC_OBJECT_TRANSFORM_ROTATE_XYZ) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const
|
bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const
|
||||||
{
|
{
|
||||||
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||||
|
@ -3422,7 +3731,7 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection,
|
||||||
if (Camera->IsSelected())
|
if (Camera->IsSelected())
|
||||||
{
|
{
|
||||||
Selection.Add(Camera);
|
Selection.Add(Camera);
|
||||||
*Flags |= LC_SEL_SELECTED;
|
*Flags |= LC_SEL_SELECTED | LC_SEL_CAMERA;
|
||||||
|
|
||||||
if (Camera->IsFocused())
|
if (Camera->IsFocused())
|
||||||
*Focus = Camera;
|
*Focus = Camera;
|
||||||
|
@ -3434,7 +3743,7 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection,
|
||||||
if (Light->IsSelected())
|
if (Light->IsSelected())
|
||||||
{
|
{
|
||||||
Selection.Add(Light);
|
Selection.Add(Light);
|
||||||
*Flags |= LC_SEL_SELECTED;
|
*Flags |= LC_SEL_SELECTED | LC_SEL_LIGHT;
|
||||||
|
|
||||||
if (Light->IsFocused())
|
if (Light->IsFocused())
|
||||||
*Focus = Light;
|
*Focus = Light;
|
||||||
|
@ -3940,6 +4249,7 @@ void lcModel::RedoAction()
|
||||||
void lcModel::BeginMouseTool()
|
void lcModel::BeginMouseTool()
|
||||||
{
|
{
|
||||||
mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f);
|
mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f);
|
||||||
|
mMouseToolFirstMove = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcModel::EndMouseTool(lcTool Tool, bool Accept)
|
void lcModel::EndMouseTool(lcTool Tool, bool Accept)
|
||||||
|
@ -3954,11 +4264,10 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept)
|
||||||
switch (Tool)
|
switch (Tool)
|
||||||
{
|
{
|
||||||
case lcTool::Insert:
|
case lcTool::Insert:
|
||||||
case lcTool::Light:
|
case lcTool::PointLight:
|
||||||
break;
|
|
||||||
|
|
||||||
case lcTool::SpotLight:
|
case lcTool::SpotLight:
|
||||||
SaveCheckpoint(tr("New SpotLight"));
|
case lcTool::DirectionalLight:
|
||||||
|
case lcTool::AreaLight:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTool::Camera:
|
case lcTool::Camera:
|
||||||
|
@ -4024,37 +4333,35 @@ void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix)
|
||||||
SaveCheckpoint(tr("Insert"));
|
SaveCheckpoint(tr("Insert"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcModel::PointLightToolClicked(const lcVector3& Position)
|
void lcModel::InsertLightToolClicked(const lcVector3& Position, lcLightType LightType)
|
||||||
{
|
{
|
||||||
lcLight* Light = new lcLight(Position[0], Position[1], Position[2]);
|
lcLight* Light = new lcLight(Position, LightType);
|
||||||
Light->CreateName(mLights);
|
Light->CreateName(mLights);
|
||||||
mLights.Add(Light);
|
mLights.Add(Light);
|
||||||
|
|
||||||
ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION, false);
|
ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION, false);
|
||||||
SaveCheckpoint(tr("New Light"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void lcModel::BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target)
|
switch (LightType)
|
||||||
{
|
{
|
||||||
lcLight* Light = new lcLight(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]);
|
case lcLightType::Point:
|
||||||
mLights.Add(Light);
|
SaveCheckpoint(tr("New Point Light"));
|
||||||
|
break;
|
||||||
|
|
||||||
mMouseToolDistance = Target;
|
case lcLightType::Spot:
|
||||||
|
SaveCheckpoint(tr("New Spot Light"));
|
||||||
|
break;
|
||||||
|
|
||||||
ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_TARGET, false);
|
case lcLightType::Directional:
|
||||||
}
|
SaveCheckpoint(tr("New Directional Light"));
|
||||||
|
break;
|
||||||
|
|
||||||
void lcModel::UpdateSpotLightTool(const lcVector3& Position)
|
case lcLightType::Area:
|
||||||
{
|
SaveCheckpoint(tr("New Area Light"));
|
||||||
lcLight* Light = mLights[mLights.GetSize() - 1];
|
break;
|
||||||
|
|
||||||
Light->MoveSelected(1, false, Position - mMouseToolDistance);
|
case lcLightType::Count:
|
||||||
Light->UpdatePosition(1);
|
break;
|
||||||
|
}
|
||||||
mMouseToolDistance = Position;
|
|
||||||
|
|
||||||
gMainWindow->UpdateSelectedObjects(false);
|
|
||||||
UpdateAllViews();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcModel::BeginCameraTool(const lcVector3& Position, const lcVector3& Target)
|
void lcModel::BeginCameraTool(const lcVector3& Position, const lcVector3& Target)
|
||||||
|
@ -4064,6 +4371,7 @@ void lcModel::BeginCameraTool(const lcVector3& Position, const lcVector3& Target
|
||||||
mCameras.Add(Camera);
|
mCameras.Add(Camera);
|
||||||
|
|
||||||
mMouseToolDistance = Position;
|
mMouseToolDistance = Position;
|
||||||
|
mMouseToolFirstMove = false;
|
||||||
|
|
||||||
ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET, false);
|
ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET, false);
|
||||||
}
|
}
|
||||||
|
@ -4076,6 +4384,7 @@ void lcModel::UpdateCameraTool(const lcVector3& Position)
|
||||||
Camera->UpdatePosition(1);
|
Camera->UpdatePosition(1);
|
||||||
|
|
||||||
mMouseToolDistance = Position;
|
mMouseToolDistance = Position;
|
||||||
|
mMouseToolFirstMove = false;
|
||||||
|
|
||||||
gMainWindow->UpdateSelectedObjects(false);
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
UpdateAllViews();
|
UpdateAllViews();
|
||||||
|
@ -4086,8 +4395,10 @@ void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool
|
||||||
const lcVector3 PieceDistance = SnapPosition(Distance) - SnapPosition(mMouseToolDistance);
|
const lcVector3 PieceDistance = SnapPosition(Distance) - SnapPosition(mMouseToolDistance);
|
||||||
const lcVector3 ObjectDistance = Distance - mMouseToolDistance;
|
const lcVector3 ObjectDistance = Distance - mMouseToolDistance;
|
||||||
|
|
||||||
MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false);
|
MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false, mMouseToolFirstMove);
|
||||||
|
|
||||||
mMouseToolDistance = Distance;
|
mMouseToolDistance = Distance;
|
||||||
|
mMouseToolFirstMove = false;
|
||||||
|
|
||||||
gMainWindow->UpdateSelectedObjects(false);
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
UpdateAllViews();
|
UpdateAllViews();
|
||||||
|
@ -4096,8 +4407,10 @@ void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool
|
||||||
void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag)
|
void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag)
|
||||||
{
|
{
|
||||||
const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance);
|
const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance);
|
||||||
RotateSelectedPieces(Delta, true, AlternateButtonDrag, false, false);
|
RotateSelectedObjects(Delta, true, AlternateButtonDrag, false, false);
|
||||||
|
|
||||||
mMouseToolDistance = Angles;
|
mMouseToolDistance = Angles;
|
||||||
|
mMouseToolFirstMove = false;
|
||||||
|
|
||||||
gMainWindow->UpdateSelectedObjects(false);
|
gMainWindow->UpdateSelectedObjects(false);
|
||||||
UpdateAllViews();
|
UpdateAllViews();
|
||||||
|
@ -4347,7 +4660,7 @@ void lcModel::ShowArrayDialog()
|
||||||
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No pieces selected."));
|
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No pieces selected."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcArrayDialog Dialog(gMainWindow);
|
lcArrayDialog Dialog(gMainWindow);
|
||||||
|
|
||||||
if (Dialog.exec() != QDialog::Accepted)
|
if (Dialog.exec() != QDialog::Accepted)
|
||||||
|
|
|
@ -5,18 +5,20 @@
|
||||||
#include "lc_array.h"
|
#include "lc_array.h"
|
||||||
|
|
||||||
#define LC_SEL_NO_PIECES 0x0001 // No pieces in model
|
#define LC_SEL_NO_PIECES 0x0001 // No pieces in model
|
||||||
#define LC_SEL_PIECE 0x0002 // At last 1 piece selected
|
#define LC_SEL_PIECE 0x0002 // At least 1 piece selected
|
||||||
#define LC_SEL_SELECTED 0x0004 // At last 1 object selected
|
#define LC_SEL_CAMERA 0x0004 // At least 1 camera selected
|
||||||
#define LC_SEL_UNSELECTED 0x0008 // At least 1 piece unselected
|
#define LC_SEL_LIGHT 0x0008 // At least 1 light selected
|
||||||
#define LC_SEL_HIDDEN 0x0010 // At least one piece hidden
|
#define LC_SEL_SELECTED 0x0010 // At least 1 object selected
|
||||||
#define LC_SEL_HIDDEN_SELECTED 0x0020 // At least one piece selected is hidden
|
#define LC_SEL_UNSELECTED 0x0020 // At least 1 piece unselected
|
||||||
#define LC_SEL_VISIBLE_SELECTED 0x0040 // At least one piece selected is not hidden
|
#define LC_SEL_HIDDEN 0x0040 // At least one piece hidden
|
||||||
#define LC_SEL_GROUPED 0x0080 // At least one piece selected is grouped
|
#define LC_SEL_HIDDEN_SELECTED 0x0080 // At least one piece selected is hidden
|
||||||
#define LC_SEL_FOCUS_GROUPED 0x0100 // Focused piece is grouped
|
#define LC_SEL_VISIBLE_SELECTED 0x0100 // At least one piece selected is not hidden
|
||||||
#define LC_SEL_CAN_GROUP 0x0200 // Can make a new group
|
#define LC_SEL_GROUPED 0x0200 // At least one piece selected is grouped
|
||||||
#define LC_SEL_MODEL_SELECTED 0x0400 // At least one model reference is selected
|
#define LC_SEL_FOCUS_GROUPED 0x0400 // Focused piece is grouped
|
||||||
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x0800 // Can add control points to focused piece
|
#define LC_SEL_CAN_GROUP 0x0800 // Can make a new group
|
||||||
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x1000 // Can remove control points from focused piece
|
#define LC_SEL_MODEL_SELECTED 0x1000 // At least one model reference is selected
|
||||||
|
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x2000 // Can add control points to focused piece
|
||||||
|
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x4000 // Can remove control points from focused piece
|
||||||
|
|
||||||
enum class lcSelectionMode
|
enum class lcSelectionMode
|
||||||
{
|
{
|
||||||
|
@ -67,6 +69,26 @@ public:
|
||||||
lcVector3 mAmbientColor;
|
lcVector3 mAmbientColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class lcPOVRayOptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcPOVRayOptions();
|
||||||
|
void ParseLDrawLine(QTextStream& LineStream);
|
||||||
|
void SaveLDraw(QTextStream& Stream) const;
|
||||||
|
|
||||||
|
bool UseLGEO;
|
||||||
|
bool ExcludeFloor;
|
||||||
|
bool ExcludeBackground;
|
||||||
|
bool NoReflection;
|
||||||
|
bool NoShadow;
|
||||||
|
int FloorAxis;
|
||||||
|
float FloorAmbient;
|
||||||
|
float FloorDiffuse;
|
||||||
|
lcVector3 FloorColor;
|
||||||
|
QString HeaderIncludeFile;
|
||||||
|
QString FooterIncludeFile;
|
||||||
|
};
|
||||||
|
|
||||||
struct lcModelHistoryEntry
|
struct lcModelHistoryEntry
|
||||||
{
|
{
|
||||||
QByteArray File;
|
QByteArray File;
|
||||||
|
@ -136,6 +158,11 @@ public:
|
||||||
return mProperties;
|
return mProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const lcPOVRayOptions& GetPOVRayOptions() const
|
||||||
|
{
|
||||||
|
return mPOVRayOptions;
|
||||||
|
}
|
||||||
|
|
||||||
void SetFileName(const QString& FileName)
|
void SetFileName(const QString& FileName)
|
||||||
{
|
{
|
||||||
if (mProperties.mModelName == mProperties.mFileName)
|
if (mProperties.mModelName == mProperties.mFileName)
|
||||||
|
@ -254,6 +281,7 @@ public:
|
||||||
lcModel* GetFirstSelectedSubmodel() const;
|
lcModel* GetFirstSelectedSubmodel() const;
|
||||||
void GetSubModels(lcArray<lcModel*>& SubModels) const;
|
void GetSubModels(lcArray<lcModel*>& SubModels) const;
|
||||||
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
|
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
|
||||||
|
bool CanRotateSelection() const;
|
||||||
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
|
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
|
||||||
lcVector3 GetSelectionOrModelCenter() const;
|
lcVector3 GetSelectionOrModelCenter() const;
|
||||||
bool GetFocusPosition(lcVector3& Position) const;
|
bool GetFocusPosition(lcVector3& Position) const;
|
||||||
|
@ -301,9 +329,7 @@ public:
|
||||||
void BeginMouseTool();
|
void BeginMouseTool();
|
||||||
void EndMouseTool(lcTool Tool, bool Accept);
|
void EndMouseTool(lcTool Tool, bool Accept);
|
||||||
void InsertPieceToolClicked(const lcMatrix44& WorldMatrix);
|
void InsertPieceToolClicked(const lcMatrix44& WorldMatrix);
|
||||||
void PointLightToolClicked(const lcVector3& Position);
|
void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType);
|
||||||
void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target);
|
|
||||||
void UpdateSpotLightTool(const lcVector3& Position);
|
|
||||||
void BeginCameraTool(const lcVector3& Position, const lcVector3& Target);
|
void BeginCameraTool(const lcVector3& Position, const lcVector3& Target);
|
||||||
void UpdateCameraTool(const lcVector3& Position);
|
void UpdateCameraTool(const lcVector3& Position);
|
||||||
void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag);
|
void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag);
|
||||||
|
@ -322,13 +348,13 @@ public:
|
||||||
void ZoomExtents(lcCamera* Camera, float Aspect);
|
void ZoomExtents(lcCamera* Camera, float Aspect);
|
||||||
void Zoom(lcCamera* Camera, float Amount);
|
void Zoom(lcCamera* Camera, float Amount);
|
||||||
|
|
||||||
void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint)
|
void MoveSelectedObjects(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove)
|
||||||
{
|
{
|
||||||
MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint);
|
MoveSelectedObjects(Distance, Distance, AllowRelative, AlternateButtonDrag, Update, Checkpoint, FirstMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint);
|
void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove);
|
||||||
void RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint);
|
void RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint);
|
||||||
void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint);
|
void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint);
|
||||||
void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform);
|
void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform);
|
||||||
void SetSelectedPiecesColorIndex(int ColorIndex);
|
void SetSelectedPiecesColorIndex(int ColorIndex);
|
||||||
|
@ -342,6 +368,20 @@ public:
|
||||||
void SetCameraZFar(lcCamera* Camera, float ZFar);
|
void SetCameraZFar(lcCamera* Camera, float ZFar);
|
||||||
void SetCameraName(lcCamera* Camera, const QString& Name);
|
void SetCameraName(lcCamera* Camera, const QString& Name);
|
||||||
|
|
||||||
|
void SetLightType(lcLight* Light, lcLightType LightType);
|
||||||
|
void SetLightColor(lcLight* Light, const lcVector3& Color);
|
||||||
|
void SetLightAttenuationDistance(lcLight* Light, float Distance);
|
||||||
|
void SetLightAttenuationPower(lcLight* Light, float Power);
|
||||||
|
void SetSpotLightConeAngle(lcLight* Light, float Angle);
|
||||||
|
void SetSpotLightPenumbraAngle(lcLight* Light, float Angle);
|
||||||
|
void SetSpotLightTightness(lcLight* Light, float Tightness);
|
||||||
|
void SetLightAreaShape(lcLight* Light, lcLightAreaShape LightAreaShape);
|
||||||
|
void SetLightAreaGrid(lcLight* Light, lcVector2i AreaGrid);
|
||||||
|
void SetLightSize(lcLight* Light, lcVector2 LightAreaSize);
|
||||||
|
void SetLightPower(lcLight* Light, float Power);
|
||||||
|
void SetLightCastShadow(lcLight* Light, bool CastShadow);
|
||||||
|
void SetLightName(lcLight* Light, const QString& Name);
|
||||||
|
|
||||||
void ShowPropertiesDialog();
|
void ShowPropertiesDialog();
|
||||||
void ShowSelectByNameDialog();
|
void ShowSelectByNameDialog();
|
||||||
void ShowArrayDialog();
|
void ShowArrayDialog();
|
||||||
|
@ -363,6 +403,7 @@ protected:
|
||||||
void AddPiece(lcPiece* Piece);
|
void AddPiece(lcPiece* Piece);
|
||||||
void InsertPiece(lcPiece* Piece, int Index);
|
void InsertPiece(lcPiece* Piece, int Index);
|
||||||
|
|
||||||
|
lcPOVRayOptions mPOVRayOptions;
|
||||||
lcModelProperties mProperties;
|
lcModelProperties mProperties;
|
||||||
Project* const mProject;
|
Project* const mProject;
|
||||||
PieceInfo* mPieceInfo;
|
PieceInfo* mPieceInfo;
|
||||||
|
@ -371,6 +412,7 @@ protected:
|
||||||
bool mActive;
|
bool mActive;
|
||||||
lcStep mCurrentStep;
|
lcStep mCurrentStep;
|
||||||
lcVector3 mMouseToolDistance;
|
lcVector3 mMouseToolDistance;
|
||||||
|
bool mMouseToolFirstMove;
|
||||||
|
|
||||||
lcArray<lcPiece*> mPieces;
|
lcArray<lcPiece*> mPieces;
|
||||||
lcArray<lcCamera*> mCameras;
|
lcArray<lcCamera*> mCameras;
|
||||||
|
|
|
@ -148,6 +148,7 @@ static lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] =
|
||||||
lcProfileEntry("Blender", "LDrawConfigPath", ""), // LC_PROFILE_BLENDER_LDRAW_CONFIG_PATH
|
lcProfileEntry("Blender", "LDrawConfigPath", ""), // LC_PROFILE_BLENDER_LDRAW_CONFIG_PATH
|
||||||
lcProfileEntry("Blender", "Version", ""), // LC_PROFILE_BLENDER_VERSION
|
lcProfileEntry("Blender", "Version", ""), // LC_PROFILE_BLENDER_VERSION
|
||||||
lcProfileEntry("Blender", "AddonVersion", ""), // LC_PROFILE_BLENDER_ADDON_VERSION
|
lcProfileEntry("Blender", "AddonVersion", ""), // LC_PROFILE_BLENDER_ADDON_VERSION
|
||||||
|
lcProfileEntry("Blender", "AddonVersionCheck", 1), // LC_PROFILE_BLENDER_ADDON_VERSION_CHECK
|
||||||
lcProfileEntry("Blender", "ImportModule", ""), // LC_PROFILE_BLENDER_IMPORT_MODULE
|
lcProfileEntry("Blender", "ImportModule", ""), // LC_PROFILE_BLENDER_IMPORT_MODULE
|
||||||
|
|
||||||
lcProfileEntry("Settgins", "PreviewViewSphereEnabled", 0), // LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED
|
lcProfileEntry("Settgins", "PreviewViewSphereEnabled", 0), // LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED
|
||||||
|
|
|
@ -94,6 +94,7 @@ enum LC_PROFILE_KEY
|
||||||
LC_PROFILE_BLENDER_LDRAW_CONFIG_PATH,
|
LC_PROFILE_BLENDER_LDRAW_CONFIG_PATH,
|
||||||
LC_PROFILE_BLENDER_VERSION,
|
LC_PROFILE_BLENDER_VERSION,
|
||||||
LC_PROFILE_BLENDER_ADDON_VERSION,
|
LC_PROFILE_BLENDER_ADDON_VERSION,
|
||||||
|
LC_PROFILE_BLENDER_ADDON_VERSION_CHECK,
|
||||||
LC_PROFILE_BLENDER_IMPORT_MODULE,
|
LC_PROFILE_BLENDER_IMPORT_MODULE,
|
||||||
|
|
||||||
LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED,
|
LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED,
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "lc_viewwidget.h"
|
#include "lc_viewwidget.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "lc_mainwindow.h"
|
#include "lc_mainwindow.h"
|
||||||
|
#include "light.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "texfont.h"
|
#include "texfont.h"
|
||||||
#include "lc_texture.h"
|
#include "lc_texture.h"
|
||||||
|
@ -415,7 +416,7 @@ lcMatrix44 lcView::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info)
|
||||||
lcModel* ActiveModel = GetActiveModel();
|
lcModel* ActiveModel = GetActiveModel();
|
||||||
|
|
||||||
lcPieceInfoRayTest PieceInfoRayTest = FindPieceInfoUnderPointer(IgnoreSelected);
|
lcPieceInfoRayTest PieceInfoRayTest = FindPieceInfoUnderPointer(IgnoreSelected);
|
||||||
|
|
||||||
if (PieceInfoRayTest.Info)
|
if (PieceInfoRayTest.Info)
|
||||||
{
|
{
|
||||||
lcVector3 Position = PieceInfoRayTest.Plane;
|
lcVector3 Position = PieceInfoRayTest.Plane;
|
||||||
|
@ -927,7 +928,7 @@ void lcView::OnDraw()
|
||||||
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
|
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
|
||||||
else if (GetCurrentTool() == lcTool::Move && mTrackButton != lcTrackButton::None)
|
else if (GetCurrentTool() == lcTool::Move && mTrackButton != lcTrackButton::None)
|
||||||
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
|
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
|
||||||
else if ((Tool == lcTool::Rotate || (Tool == lcTool::Select && mTrackButton != lcTrackButton::None && mTrackTool >= lcTrackTool::RotateX && mTrackTool <= lcTrackTool::RotateXYZ)) && ActiveModel->AnyPiecesSelected())
|
else if ((Tool == lcTool::Rotate || (Tool == lcTool::Select && mTrackButton != lcTrackButton::None && mTrackTool >= lcTrackTool::RotateX && mTrackTool <= lcTrackTool::RotateXYZ)) && ActiveModel->CanRotateSelection())
|
||||||
mViewManipulator->DrawRotate(mTrackButton, mTrackTool);
|
mViewManipulator->DrawRotate(mTrackButton, mTrackTool);
|
||||||
else if ((mTrackTool == lcTrackTool::Select || mTrackTool == lcTrackTool::ZoomRegion) && mTrackButton != lcTrackButton::None)
|
else if ((mTrackTool == lcTrackTool::Select || mTrackTool == lcTrackTool::ZoomRegion) && mTrackButton != lcTrackButton::None)
|
||||||
DrawSelectZoomRegionOverlay();
|
DrawSelectZoomRegionOverlay();
|
||||||
|
@ -1361,7 +1362,7 @@ void lcView::DrawRotateViewOverlay()
|
||||||
mContext->SetVertexBufferPointer(Verts);
|
mContext->SetVertexBufferPointer(Verts);
|
||||||
mContext->SetVertexFormatPosition(2);
|
mContext->SetVertexFormatPosition(2);
|
||||||
|
|
||||||
GLushort Indices[64 + 32] =
|
GLushort Indices[64 + 32] =
|
||||||
{
|
{
|
||||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
|
||||||
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 0,
|
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 0,
|
||||||
|
@ -1594,21 +1595,23 @@ lcTrackTool lcView::GetOverrideTrackTool(Qt::MouseButton Button) const
|
||||||
|
|
||||||
constexpr lcTrackTool TrackToolFromTool[] =
|
constexpr lcTrackTool TrackToolFromTool[] =
|
||||||
{
|
{
|
||||||
lcTrackTool::Insert, // lcTool::Insert
|
lcTrackTool::Insert, // lcTool::Insert
|
||||||
lcTrackTool::PointLight, // lcTool::Light
|
lcTrackTool::PointLight, // lcTool::PointLight
|
||||||
lcTrackTool::SpotLight, // lcTool::SpotLight
|
lcTrackTool::SpotLight, // lcTool::SpotLight
|
||||||
lcTrackTool::Camera, // lcTool::Camera
|
lcTrackTool::DirectionalLight, // lcTool::DirectionalLight
|
||||||
lcTrackTool::Select, // lcTool::Select
|
lcTrackTool::AreaLight, // lcTool::AreaLight
|
||||||
lcTrackTool::MoveXYZ, // lcTool::Move
|
lcTrackTool::Camera, // lcTool::Camera
|
||||||
lcTrackTool::RotateXYZ, // lcTool::Rotate
|
lcTrackTool::Select, // lcTool::Select
|
||||||
lcTrackTool::Eraser, // lcTool::Eraser
|
lcTrackTool::MoveXYZ, // lcTool::Move
|
||||||
lcTrackTool::Paint, // lcTool::Paint
|
lcTrackTool::RotateXYZ, // lcTool::Rotate
|
||||||
lcTrackTool::ColorPicker, // lcTool::ColorPicker
|
lcTrackTool::Eraser, // lcTool::Eraser
|
||||||
lcTrackTool::Zoom, // lcTool::Zoom
|
lcTrackTool::Paint, // lcTool::Paint
|
||||||
lcTrackTool::Pan, // lcTool::Pan
|
lcTrackTool::ColorPicker, // lcTool::ColorPicker
|
||||||
lcTrackTool::OrbitXY, // lcTool::RotateView
|
lcTrackTool::Zoom, // lcTool::Zoom
|
||||||
lcTrackTool::Roll, // lcTool::Roll
|
lcTrackTool::Pan, // lcTool::Pan
|
||||||
lcTrackTool::ZoomRegion // lcTool::ZoomRegion
|
lcTrackTool::OrbitXY, // lcTool::RotateView
|
||||||
|
lcTrackTool::Roll, // lcTool::Roll
|
||||||
|
lcTrackTool::ZoomRegion // lcTool::ZoomRegion
|
||||||
};
|
};
|
||||||
|
|
||||||
LC_ARRAY_SIZE_CHECK(TrackToolFromTool, lcTool::Count);
|
LC_ARRAY_SIZE_CHECK(TrackToolFromTool, lcTool::Count);
|
||||||
|
@ -1864,36 +1867,38 @@ lcCursor lcView::GetCursor() const
|
||||||
|
|
||||||
constexpr lcCursor CursorFromTrackTool[] =
|
constexpr lcCursor CursorFromTrackTool[] =
|
||||||
{
|
{
|
||||||
lcCursor::Select, // lcTrackTool::None
|
lcCursor::Select, // lcTrackTool::None
|
||||||
lcCursor::Brick, // lcTrackTool::Insert
|
lcCursor::Brick, // lcTrackTool::Insert
|
||||||
lcCursor::Light, // lcTrackTool::PointLight
|
lcCursor::PointLight, // lcTrackTool::PointLight
|
||||||
lcCursor::Spotlight, // lcTrackTool::SpotLight
|
lcCursor::SpotLight, // lcTrackTool::SpotLight
|
||||||
lcCursor::Camera, // lcTrackTool::Camera
|
lcCursor::DirectionalLight, // lcTrackTool::DirectionalLight
|
||||||
lcCursor::Select, // lcTrackTool::Select
|
lcCursor::AreaLight, // lcTrackTool::AreaLight
|
||||||
lcCursor::Move, // lcTrackTool::MoveX
|
lcCursor::Camera, // lcTrackTool::Camera
|
||||||
lcCursor::Move, // lcTrackTool::MoveY
|
lcCursor::Select, // lcTrackTool::Select
|
||||||
lcCursor::Move, // lcTrackTool::MoveZ
|
lcCursor::Move, // lcTrackTool::MoveX
|
||||||
lcCursor::Move, // lcTrackTool::MoveXY
|
lcCursor::Move, // lcTrackTool::MoveY
|
||||||
lcCursor::Move, // lcTrackTool::MoveXZ
|
lcCursor::Move, // lcTrackTool::MoveZ
|
||||||
lcCursor::Move, // lcTrackTool::MoveYZ
|
lcCursor::Move, // lcTrackTool::MoveXY
|
||||||
lcCursor::Move, // lcTrackTool::MoveXYZ
|
lcCursor::Move, // lcTrackTool::MoveXZ
|
||||||
lcCursor::Rotate, // lcTrackTool::RotateX
|
lcCursor::Move, // lcTrackTool::MoveYZ
|
||||||
lcCursor::Rotate, // lcTrackTool::RotateY
|
lcCursor::Move, // lcTrackTool::MoveXYZ
|
||||||
lcCursor::Rotate, // lcTrackTool::RotateZ
|
lcCursor::Rotate, // lcTrackTool::RotateX
|
||||||
lcCursor::Rotate, // lcTrackTool::RotateXY
|
lcCursor::Rotate, // lcTrackTool::RotateY
|
||||||
lcCursor::Rotate, // lcTrackTool::RotateXYZ
|
lcCursor::Rotate, // lcTrackTool::RotateZ
|
||||||
lcCursor::Move, // lcTrackTool::ScalePlus
|
lcCursor::Rotate, // lcTrackTool::RotateXY
|
||||||
lcCursor::Move, // lcTrackTool::ScaleMinus
|
lcCursor::Rotate, // lcTrackTool::RotateXYZ
|
||||||
lcCursor::Delete, // lcTrackTool::Eraser
|
lcCursor::Move, // lcTrackTool::ScalePlus
|
||||||
lcCursor::Paint, // lcTrackTool::Paint
|
lcCursor::Move, // lcTrackTool::ScaleMinus
|
||||||
lcCursor::ColorPicker, // lcTrackTool::ColorPicker
|
lcCursor::Delete, // lcTrackTool::Eraser
|
||||||
lcCursor::Zoom, // lcTrackTool::Zoom
|
lcCursor::Paint, // lcTrackTool::Paint
|
||||||
lcCursor::Pan, // lcTrackTool::Pan
|
lcCursor::ColorPicker, // lcTrackTool::ColorPicker
|
||||||
lcCursor::RotateX, // lcTrackTool::OrbitX
|
lcCursor::Zoom, // lcTrackTool::Zoom
|
||||||
lcCursor::RotateY, // lcTrackTool::OrbitY
|
lcCursor::Pan, // lcTrackTool::Pan
|
||||||
lcCursor::RotateView, // lcTrackTool::OrbitXY
|
lcCursor::RotateX, // lcTrackTool::OrbitX
|
||||||
lcCursor::Roll, // lcTrackTool::Roll
|
lcCursor::RotateY, // lcTrackTool::OrbitY
|
||||||
lcCursor::ZoomRegion // lcTrackTool::ZoomRegion
|
lcCursor::RotateView, // lcTrackTool::OrbitXY
|
||||||
|
lcCursor::Roll, // lcTrackTool::Roll
|
||||||
|
lcCursor::ZoomRegion // lcTrackTool::ZoomRegion
|
||||||
};
|
};
|
||||||
|
|
||||||
LC_ARRAY_SIZE_CHECK(CursorFromTrackTool, lcTrackTool::Count);
|
LC_ARRAY_SIZE_CHECK(CursorFromTrackTool, lcTrackTool::Count);
|
||||||
|
@ -1920,8 +1925,10 @@ void lcView::SetCursor(lcCursor CursorType)
|
||||||
{ 0, 0, "" }, // lcCursor::Hidden
|
{ 0, 0, "" }, // lcCursor::Hidden
|
||||||
{ 0, 0, "" }, // lcCursor::Default
|
{ 0, 0, "" }, // lcCursor::Default
|
||||||
{ 8, 3, ":/resources/cursor_insert" }, // lcCursor::Brick
|
{ 8, 3, ":/resources/cursor_insert" }, // lcCursor::Brick
|
||||||
{ 15, 15, ":/resources/cursor_light" }, // lcCursor::Light
|
{ 15, 15, ":/resources/cursor_light" }, // lcCursor::PointLight
|
||||||
{ 7, 10, ":/resources/cursor_spotlight" }, // lcCursor::Spotlight
|
{ 7, 10, ":/resources/cursor_spotlight" }, // lcCursor::SpotLight
|
||||||
|
{ 15, 15, ":/resources/cursor_sunlight" }, // lcCursor::DirectionalLight
|
||||||
|
{ 15, 15, ":/resources/cursor_arealight" }, // lcCursor::AreaLight
|
||||||
{ 15, 9, ":/resources/cursor_camera" }, // lcCursor::Camera
|
{ 15, 9, ":/resources/cursor_camera" }, // lcCursor::Camera
|
||||||
{ 0, 2, ":/resources/cursor_select" }, // lcCursor::Select
|
{ 0, 2, ":/resources/cursor_select" }, // lcCursor::Select
|
||||||
{ 0, 2, ":/resources/cursor_select_add" }, // lcCursor::SelectAdd
|
{ 0, 2, ":/resources/cursor_select_add" }, // lcCursor::SelectAdd
|
||||||
|
@ -1969,36 +1976,38 @@ lcTool lcView::GetCurrentTool() const
|
||||||
{
|
{
|
||||||
constexpr lcTool ToolFromTrackTool[] =
|
constexpr lcTool ToolFromTrackTool[] =
|
||||||
{
|
{
|
||||||
lcTool::Select, // lcTrackTool::None
|
lcTool::Select, // lcTrackTool::None
|
||||||
lcTool::Insert, // lcTrackTool::Insert
|
lcTool::Insert, // lcTrackTool::Insert
|
||||||
lcTool::Light, // lcTrackTool::PointLight
|
lcTool::PointLight, // lcTrackTool::PointLight
|
||||||
lcTool::SpotLight, // lcTrackTool::SpotLight
|
lcTool::SpotLight, // lcTrackTool::SpotLight
|
||||||
lcTool::Camera, // lcTrackTool::Camera
|
lcTool::DirectionalLight, // lcTrackTool::DirectionalLight
|
||||||
lcTool::Select, // lcTrackTool::Select
|
lcTool::AreaLight, // lcTrackTool::AreaLight
|
||||||
lcTool::Move, // lcTrackTool::MoveX
|
lcTool::Camera, // lcTrackTool::Camera
|
||||||
lcTool::Move, // lcTrackTool::MoveY
|
lcTool::Select, // lcTrackTool::Select
|
||||||
lcTool::Move, // lcTrackTool::MoveZ
|
lcTool::Move, // lcTrackTool::MoveX
|
||||||
lcTool::Move, // lcTrackTool::MoveXY
|
lcTool::Move, // lcTrackTool::MoveY
|
||||||
lcTool::Move, // lcTrackTool::MoveXZ
|
lcTool::Move, // lcTrackTool::MoveZ
|
||||||
lcTool::Move, // lcTrackTool::MoveYZ
|
lcTool::Move, // lcTrackTool::MoveXY
|
||||||
lcTool::Move, // lcTrackTool::MoveXYZ
|
lcTool::Move, // lcTrackTool::MoveXZ
|
||||||
lcTool::Rotate, // lcTrackTool::RotateX
|
lcTool::Move, // lcTrackTool::MoveYZ
|
||||||
lcTool::Rotate, // lcTrackTool::RotateY
|
lcTool::Move, // lcTrackTool::MoveXYZ
|
||||||
lcTool::Rotate, // lcTrackTool::RotateZ
|
lcTool::Rotate, // lcTrackTool::RotateX
|
||||||
lcTool::Rotate, // lcTrackTool::RotateXY
|
lcTool::Rotate, // lcTrackTool::RotateY
|
||||||
lcTool::Rotate, // lcTrackTool::RotateXYZ
|
lcTool::Rotate, // lcTrackTool::RotateZ
|
||||||
lcTool::Move, // lcTrackTool::ScalePlus
|
lcTool::Rotate, // lcTrackTool::RotateXY
|
||||||
lcTool::Move, // lcTrackTool::ScaleMinus
|
lcTool::Rotate, // lcTrackTool::RotateXYZ
|
||||||
lcTool::Eraser, // lcTrackTool::Eraser
|
lcTool::Move, // lcTrackTool::ScalePlus
|
||||||
lcTool::Paint, // lcTrackTool::Paint
|
lcTool::Move, // lcTrackTool::ScaleMinus
|
||||||
lcTool::ColorPicker, // lcTrackTool::ColorPicker
|
lcTool::Eraser, // lcTrackTool::Eraser
|
||||||
lcTool::Zoom, // lcTrackTool::Zoom
|
lcTool::Paint, // lcTrackTool::Paint
|
||||||
lcTool::Pan, // lcTrackTool::Pan
|
lcTool::ColorPicker, // lcTrackTool::ColorPicker
|
||||||
lcTool::RotateView, // lcTrackTool::OrbitX
|
lcTool::Zoom, // lcTrackTool::Zoom
|
||||||
lcTool::RotateView, // lcTrackTool::OrbitY
|
lcTool::Pan, // lcTrackTool::Pan
|
||||||
lcTool::RotateView, // lcTrackTool::OrbitXY
|
lcTool::RotateView, // lcTrackTool::OrbitX
|
||||||
lcTool::Roll, // lcTrackTool::Roll
|
lcTool::RotateView, // lcTrackTool::OrbitY
|
||||||
lcTool::ZoomRegion // lcTrackTool::ZoomRegion
|
lcTool::RotateView, // lcTrackTool::OrbitXY
|
||||||
|
lcTool::Roll, // lcTrackTool::Roll
|
||||||
|
lcTool::ZoomRegion // lcTrackTool::ZoomRegion
|
||||||
};
|
};
|
||||||
|
|
||||||
LC_ARRAY_SIZE_CHECK(ToolFromTrackTool, lcTrackTool::Count);
|
LC_ARRAY_SIZE_CHECK(ToolFromTrackTool, lcTrackTool::Count);
|
||||||
|
@ -2032,7 +2041,7 @@ void lcView::UpdateTrackTool()
|
||||||
NewTrackTool = lcTrackTool::Insert;
|
NewTrackTool = lcTrackTool::Insert;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTool::Light:
|
case lcTool::PointLight:
|
||||||
NewTrackTool = lcTrackTool::PointLight;
|
NewTrackTool = lcTrackTool::PointLight;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2040,6 +2049,14 @@ void lcView::UpdateTrackTool()
|
||||||
NewTrackTool = lcTrackTool::SpotLight;
|
NewTrackTool = lcTrackTool::SpotLight;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case lcTool::DirectionalLight:
|
||||||
|
NewTrackTool = lcTrackTool::DirectionalLight;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcTool::AreaLight:
|
||||||
|
NewTrackTool = lcTrackTool::AreaLight;
|
||||||
|
break;
|
||||||
|
|
||||||
case lcTool::Camera:
|
case lcTool::Camera:
|
||||||
NewTrackTool = lcTrackTool::Camera;
|
NewTrackTool = lcTrackTool::Camera;
|
||||||
break;
|
break;
|
||||||
|
@ -2258,16 +2275,11 @@ void lcView::StartTracking(lcTrackButton TrackButton)
|
||||||
switch (Tool)
|
switch (Tool)
|
||||||
{
|
{
|
||||||
case lcTool::Insert:
|
case lcTool::Insert:
|
||||||
case lcTool::Light:
|
case lcTool::PointLight:
|
||||||
break;
|
|
||||||
|
|
||||||
case lcTool::SpotLight:
|
case lcTool::SpotLight:
|
||||||
{
|
case lcTool::DirectionalLight:
|
||||||
lcVector3 Position = GetCameraLightInsertPosition();
|
case lcTool::AreaLight:
|
||||||
lcVector3 Target = Position + lcVector3(0.1f, 0.1f, 0.1f);
|
break;
|
||||||
ActiveModel->BeginSpotLightTool(Position, Target);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case lcTool::Camera:
|
case lcTool::Camera:
|
||||||
{
|
{
|
||||||
|
@ -2322,10 +2334,12 @@ void lcView::StopTracking(bool Accept)
|
||||||
switch (Tool)
|
switch (Tool)
|
||||||
{
|
{
|
||||||
case lcTool::Insert:
|
case lcTool::Insert:
|
||||||
case lcTool::Light:
|
case lcTool::PointLight:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTool::SpotLight:
|
case lcTool::SpotLight:
|
||||||
|
case lcTool::DirectionalLight:
|
||||||
|
case lcTool::AreaLight:
|
||||||
case lcTool::Camera:
|
case lcTool::Camera:
|
||||||
ActiveModel->EndMouseTool(Tool, Accept);
|
ActiveModel->EndMouseTool(Tool, Accept);
|
||||||
break;
|
break;
|
||||||
|
@ -2418,6 +2432,17 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
|
||||||
lcModel* ActiveModel = GetActiveModel();
|
lcModel* ActiveModel = GetActiveModel();
|
||||||
mToolClicked = false;
|
mToolClicked = false;
|
||||||
|
|
||||||
|
auto AddLight = [this, ActiveModel](lcLightType LightType)
|
||||||
|
{
|
||||||
|
ActiveModel->InsertLightToolClicked(GetCameraLightInsertPosition(), LightType);
|
||||||
|
|
||||||
|
if ((mMouseModifiers & Qt::ControlModifier) == 0)
|
||||||
|
gMainWindow->SetTool(lcTool::Select);
|
||||||
|
|
||||||
|
mToolClicked = true;
|
||||||
|
UpdateTrackTool();
|
||||||
|
};
|
||||||
|
|
||||||
switch (mTrackTool)
|
switch (mTrackTool)
|
||||||
{
|
{
|
||||||
case lcTrackTool::None:
|
case lcTrackTool::None:
|
||||||
|
@ -2441,22 +2466,25 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTrackTool::PointLight:
|
case lcTrackTool::PointLight:
|
||||||
{
|
AddLight(lcLightType::Point);
|
||||||
ActiveModel->PointLightToolClicked(GetCameraLightInsertPosition());
|
|
||||||
|
|
||||||
if ((mMouseModifiers & Qt::ControlModifier) == 0)
|
|
||||||
gMainWindow->SetTool(lcTool::Select);
|
|
||||||
|
|
||||||
mToolClicked = true;
|
|
||||||
UpdateTrackTool();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTrackTool::SpotLight:
|
case lcTrackTool::SpotLight:
|
||||||
|
AddLight(lcLightType::Spot);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcTrackTool::DirectionalLight:
|
||||||
|
AddLight(lcLightType::Directional);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcTrackTool::AreaLight:
|
||||||
|
AddLight(lcLightType::Area);
|
||||||
|
break;
|
||||||
|
|
||||||
case lcTrackTool::Camera:
|
case lcTrackTool::Camera:
|
||||||
StartTracking(TrackButton);
|
StartTracking(TrackButton);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTrackTool::Select:
|
case lcTrackTool::Select:
|
||||||
{
|
{
|
||||||
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
|
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
|
||||||
|
@ -2488,7 +2516,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
|
||||||
case lcTrackTool::RotateZ:
|
case lcTrackTool::RotateZ:
|
||||||
case lcTrackTool::RotateXY:
|
case lcTrackTool::RotateXY:
|
||||||
case lcTrackTool::RotateXYZ:
|
case lcTrackTool::RotateXYZ:
|
||||||
if (ActiveModel->AnyPiecesSelected())
|
if (ActiveModel->CanRotateSelection())
|
||||||
StartTracking(TrackButton);
|
StartTracking(TrackButton);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2687,10 +2715,9 @@ void lcView::OnMouseMove()
|
||||||
case lcTrackTool::None:
|
case lcTrackTool::None:
|
||||||
case lcTrackTool::Insert:
|
case lcTrackTool::Insert:
|
||||||
case lcTrackTool::PointLight:
|
case lcTrackTool::PointLight:
|
||||||
break;
|
|
||||||
|
|
||||||
case lcTrackTool::SpotLight:
|
case lcTrackTool::SpotLight:
|
||||||
ActiveModel->UpdateSpotLightTool(GetCameraLightInsertPosition());
|
case lcTrackTool::DirectionalLight:
|
||||||
|
case lcTrackTool::AreaLight:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case lcTrackTool::Camera:
|
case lcTrackTool::Camera:
|
||||||
|
|
|
@ -17,8 +17,10 @@ enum class lcCursor
|
||||||
Hidden = First,
|
Hidden = First,
|
||||||
Default,
|
Default,
|
||||||
Brick,
|
Brick,
|
||||||
Light,
|
PointLight,
|
||||||
Spotlight,
|
SpotLight,
|
||||||
|
DirectionalLight,
|
||||||
|
AreaLight,
|
||||||
Camera,
|
Camera,
|
||||||
Select,
|
Select,
|
||||||
SelectAdd,
|
SelectAdd,
|
||||||
|
@ -52,6 +54,8 @@ enum class lcTrackTool
|
||||||
Insert,
|
Insert,
|
||||||
PointLight,
|
PointLight,
|
||||||
SpotLight,
|
SpotLight,
|
||||||
|
DirectionalLight,
|
||||||
|
AreaLight,
|
||||||
Camera,
|
Camera,
|
||||||
Select,
|
Select,
|
||||||
MoveX,
|
MoveX,
|
||||||
|
|
|
@ -675,6 +675,8 @@ bool lcViewManipulator::IsTrackToolAllowed(lcTrackTool TrackTool, quint32 Allowe
|
||||||
case lcTrackTool::Insert:
|
case lcTrackTool::Insert:
|
||||||
case lcTrackTool::PointLight:
|
case lcTrackTool::PointLight:
|
||||||
case lcTrackTool::SpotLight:
|
case lcTrackTool::SpotLight:
|
||||||
|
case lcTrackTool::DirectionalLight:
|
||||||
|
case lcTrackTool::AreaLight:
|
||||||
case lcTrackTool::Camera:
|
case lcTrackTool::Camera:
|
||||||
case lcTrackTool::Select:
|
case lcTrackTool::Select:
|
||||||
return true;
|
return true;
|
||||||
|
@ -793,7 +795,7 @@ lcTrackTool lcViewManipulator::UpdateSelectMove()
|
||||||
ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST;
|
ControlPointIndex = Section - LC_PIECE_SECTION_CONTROL_POINT_FIRST;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z | LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
|
quint32 AllowedTransforms = Focus ? Focus->GetAllowedTransforms() : LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
|
||||||
|
|
||||||
for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++)
|
for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++)
|
||||||
{
|
{
|
||||||
|
|
1159
common/light.cpp
1159
common/light.cpp
File diff suppressed because it is too large
Load diff
377
common/light.h
377
common/light.h
|
@ -5,179 +5,207 @@
|
||||||
|
|
||||||
#define LC_LIGHT_HIDDEN 0x0001
|
#define LC_LIGHT_HIDDEN 0x0001
|
||||||
#define LC_LIGHT_DISABLED 0x0002
|
#define LC_LIGHT_DISABLED 0x0002
|
||||||
#define LC_LIGHT_SPOT 0x0004
|
|
||||||
#define LC_LIGHT_DIRECTIONAL 0x0008
|
|
||||||
#define LC_LIGHT_POSITION_SELECTED 0x0010
|
|
||||||
#define LC_LIGHT_POSITION_FOCUSED 0x0020
|
|
||||||
#define LC_LIGHT_TARGET_SELECTED 0x0040
|
|
||||||
#define LC_LIGHT_TARGET_FOCUSED 0x0080
|
|
||||||
|
|
||||||
#define LC_LIGHT_SELECTION_MASK (LC_LIGHT_POSITION_SELECTED | LC_LIGHT_TARGET_SELECTED)
|
enum lcLightSection : quint32
|
||||||
#define LC_LIGHT_FOCUS_MASK (LC_LIGHT_POSITION_FOCUSED | LC_LIGHT_TARGET_FOCUSED)
|
|
||||||
|
|
||||||
enum lcLightSection
|
|
||||||
{
|
{
|
||||||
LC_LIGHT_SECTION_POSITION,
|
LC_LIGHT_SECTION_INVALID = ~0U,
|
||||||
|
LC_LIGHT_SECTION_POSITION = 0,
|
||||||
LC_LIGHT_SECTION_TARGET
|
LC_LIGHT_SECTION_TARGET
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class lcLightType
|
||||||
|
{
|
||||||
|
Point,
|
||||||
|
Spot,
|
||||||
|
Directional,
|
||||||
|
Area,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class lcLightAreaShape
|
||||||
|
{
|
||||||
|
Rectangle,
|
||||||
|
Square,
|
||||||
|
Disk,
|
||||||
|
Ellipse,
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
class lcLight : public lcObject
|
class lcLight : public lcObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lcLight(float px, float py, float pz);
|
lcLight(const lcVector3& Position, lcLightType LightType);
|
||||||
lcLight(float px, float py, float pz, float tx, float ty, float tz);
|
virtual ~lcLight() = default;
|
||||||
~lcLight();
|
|
||||||
|
|
||||||
lcLight(const lcLight&) = delete;
|
lcLight(const lcLight&) = delete;
|
||||||
lcLight(lcLight&&) = delete;
|
lcLight(lcLight&&) = delete;
|
||||||
lcLight& operator=(const lcLight&) = delete;
|
lcLight& operator=(const lcLight&) = delete;
|
||||||
lcLight& operator=(lcLight&&) = delete;
|
lcLight& operator=(lcLight&&) = delete;
|
||||||
|
|
||||||
|
static QString GetLightTypeString(lcLightType LightType);
|
||||||
|
static QString GetAreaShapeString(lcLightAreaShape LightAreaShape);
|
||||||
|
|
||||||
bool IsPointLight() const
|
bool IsPointLight() const
|
||||||
{
|
{
|
||||||
return (mState & (LC_LIGHT_SPOT | LC_LIGHT_DIRECTIONAL)) == 0;
|
return mLightType == lcLightType::Point;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSpotLight() const
|
bool IsSpotLight() const
|
||||||
{
|
{
|
||||||
return (mState & LC_LIGHT_SPOT) != 0;
|
return mLightType == lcLightType::Spot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsDirectionalLight() const
|
bool IsDirectionalLight() const
|
||||||
{
|
{
|
||||||
return (mState & LC_LIGHT_DIRECTIONAL) != 0;
|
return mLightType == lcLightType::Directional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsAreaLight() const
|
||||||
|
{
|
||||||
|
return mLightType == lcLightType::Area;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcLightType GetLightType() const
|
||||||
|
{
|
||||||
|
return mLightType;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetLightType(lcLightType LightType);
|
||||||
|
|
||||||
bool IsSelected() const override
|
bool IsSelected() const override
|
||||||
{
|
{
|
||||||
return (mState & LC_LIGHT_SELECTION_MASK) != 0;
|
return mSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSelected(quint32 Section) const override
|
bool IsSelected(quint32 Section) const override
|
||||||
{
|
{
|
||||||
switch (Section)
|
Q_UNUSED(Section);
|
||||||
{
|
|
||||||
case LC_LIGHT_SECTION_POSITION:
|
|
||||||
return (mState & LC_LIGHT_POSITION_SELECTED) != 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LC_LIGHT_SECTION_TARGET:
|
return mSelected;
|
||||||
return (mState & LC_LIGHT_TARGET_SELECTED) != 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSelected(bool Selected) override
|
void SetSelected(bool Selected) override
|
||||||
{
|
{
|
||||||
if (Selected)
|
mSelected = Selected;
|
||||||
{
|
|
||||||
if (IsPointLight())
|
if (!Selected)
|
||||||
mState |= LC_LIGHT_POSITION_SELECTED;
|
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||||
else
|
|
||||||
mState |= LC_LIGHT_SELECTION_MASK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mState &= ~(LC_LIGHT_SELECTION_MASK | LC_LIGHT_FOCUS_MASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetSelected(quint32 Section, bool Selected) override
|
void SetSelected(quint32 Section, bool Selected) override
|
||||||
{
|
{
|
||||||
switch (Section)
|
Q_UNUSED(Section);
|
||||||
{
|
|
||||||
case LC_LIGHT_SECTION_POSITION:
|
|
||||||
if (Selected)
|
|
||||||
mState |= LC_LIGHT_POSITION_SELECTED;
|
|
||||||
else
|
|
||||||
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LC_LIGHT_SECTION_TARGET:
|
mSelected = Selected;
|
||||||
if (Selected)
|
|
||||||
{
|
if (!Selected)
|
||||||
if (!IsPointLight())
|
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||||
mState |= LC_LIGHT_TARGET_SELECTED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFocused() const override
|
bool IsFocused() const override
|
||||||
{
|
{
|
||||||
return (mState & LC_LIGHT_FOCUS_MASK) != 0;
|
return mFocusedSection != LC_LIGHT_SECTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFocused(quint32 Section) const override
|
bool IsFocused(quint32 Section) const override
|
||||||
{
|
{
|
||||||
switch (Section)
|
return mFocusedSection == Section;
|
||||||
{
|
|
||||||
case LC_LIGHT_SECTION_POSITION:
|
|
||||||
return (mState & LC_LIGHT_POSITION_FOCUSED) != 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LC_LIGHT_SECTION_TARGET:
|
|
||||||
return (mState & LC_LIGHT_TARGET_FOCUSED) != 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFocused(quint32 Section, bool Focused) override
|
void SetFocused(quint32 Section, bool Focused) override
|
||||||
{
|
{
|
||||||
switch (Section)
|
if (Focused)
|
||||||
{
|
{
|
||||||
case LC_LIGHT_SECTION_POSITION:
|
mFocusedSection = Section;
|
||||||
if (Focused)
|
mSelected = true;
|
||||||
mState |= LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED;
|
|
||||||
else
|
|
||||||
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LC_LIGHT_SECTION_TARGET:
|
|
||||||
if (Focused)
|
|
||||||
{
|
|
||||||
if (!IsPointLight())
|
|
||||||
mState |= LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 GetFocusSection() const override
|
quint32 GetFocusSection() const override
|
||||||
{
|
{
|
||||||
if (mState & LC_LIGHT_POSITION_FOCUSED)
|
return mFocusedSection;
|
||||||
return LC_LIGHT_SECTION_POSITION;
|
|
||||||
|
|
||||||
if (!IsPointLight() && (mState & LC_LIGHT_TARGET_FOCUSED))
|
|
||||||
return LC_LIGHT_SECTION_TARGET;
|
|
||||||
|
|
||||||
return ~0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 GetAllowedTransforms() const override
|
quint32 GetAllowedTransforms() const override
|
||||||
{
|
{
|
||||||
return LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
|
if (IsPointLight())
|
||||||
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
||||||
|
|
||||||
|
const quint32 Section = GetFocusSection();
|
||||||
|
|
||||||
|
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
|
||||||
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
|
||||||
|
|
||||||
|
if (Section == LC_LIGHT_SECTION_TARGET)
|
||||||
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcMatrix33 GetRelativeRotation() const
|
||||||
|
{
|
||||||
|
const quint32 Section = GetFocusSection();
|
||||||
|
|
||||||
|
if (Section == LC_LIGHT_SECTION_POSITION)
|
||||||
|
return lcMatrix33(mWorldMatrix);
|
||||||
|
else
|
||||||
|
return lcMatrix33Identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
lcVector3 GetSectionPosition(quint32 Section) const override
|
lcVector3 GetSectionPosition(quint32 Section) const override
|
||||||
{
|
{
|
||||||
switch (Section)
|
if (Section == LC_LIGHT_SECTION_POSITION)
|
||||||
{
|
return mWorldMatrix.GetTranslation();
|
||||||
case LC_LIGHT_SECTION_POSITION:
|
|
||||||
return mPosition;
|
|
||||||
|
|
||||||
case LC_LIGHT_SECTION_TARGET:
|
if (Section == LC_LIGHT_SECTION_TARGET)
|
||||||
return mTargetPosition;
|
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
||||||
}
|
|
||||||
|
|
||||||
return lcVector3(0.0f, 0.0f, 0.0f);
|
return lcVector3(0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetPosition(const lcVector3& Position, lcStep Step, bool AddKey)
|
||||||
|
{
|
||||||
|
mPositionKeys.ChangeKey(Position, Step, AddKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRotation(const lcMatrix33& Rotation, lcStep Step, bool AddKey)
|
||||||
|
{
|
||||||
|
mRotationKeys.ChangeKey(Rotation, Step, AddKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector3 GetRotationCenter() const
|
||||||
|
{
|
||||||
|
const quint32 Section = GetFocusSection();
|
||||||
|
|
||||||
|
if (Section == LC_LIGHT_SECTION_POSITION || Section == LC_LIGHT_SECTION_INVALID)
|
||||||
|
{
|
||||||
|
return mWorldMatrix.GetTranslation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector3 GetPosition() const
|
||||||
|
{
|
||||||
|
return mWorldMatrix.GetTranslation();
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector3 GetDirection() const
|
||||||
|
{
|
||||||
|
return -lcVector3(mWorldMatrix[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lcMatrix44& GetWorldMatrix() const
|
||||||
|
{
|
||||||
|
return mWorldMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
void SaveLDraw(QTextStream& Stream) const;
|
void SaveLDraw(QTextStream& Stream) const;
|
||||||
|
bool ParseLDrawLine(QTextStream& Stream);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
|
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
|
||||||
|
@ -189,7 +217,91 @@ public:
|
||||||
void RemoveTime(lcStep Start, lcStep Time);
|
void RemoveTime(lcStep Start, lcStep Time);
|
||||||
|
|
||||||
bool IsVisible() const
|
bool IsVisible() const
|
||||||
{ return (mState & LC_LIGHT_HIDDEN) == 0; }
|
{
|
||||||
|
return (mState & LC_LIGHT_HIDDEN) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetColor(const lcVector3& Color, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
lcVector3 GetColor() const
|
||||||
|
{
|
||||||
|
return mColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAttenuationDistance(float Distance, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
float GetAttenuationDistance() const
|
||||||
|
{
|
||||||
|
return mAttenuationDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAttenuationPower(float Power, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
float GetAttenuationPower() const
|
||||||
|
{
|
||||||
|
return mAttenuationPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSpotConeAngle(float Angle, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
float GetSpotConeAngle() const
|
||||||
|
{
|
||||||
|
return mSpotConeAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSpotPenumbraAngle(float Angle, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
float GetSpotPenumbraAngle() const
|
||||||
|
{
|
||||||
|
return mSpotPenumbraAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSpotTightness(float Angle, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
float GetSpotTightness() const
|
||||||
|
{
|
||||||
|
return mSpotTightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetAreaShape(lcLightAreaShape LightAreaShape);
|
||||||
|
|
||||||
|
lcLightAreaShape GetAreaShape() const
|
||||||
|
{
|
||||||
|
return mAreaShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetAreaGrid(lcVector2i AreaGrid, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
lcVector2i GetAreaGrid() const
|
||||||
|
{
|
||||||
|
return mAreaGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetSize(lcVector2 Size, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
lcVector2 GetSize() const
|
||||||
|
{
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPower(float Power, lcStep Step, bool AddKey);
|
||||||
|
|
||||||
|
float GetPower() const
|
||||||
|
{
|
||||||
|
return mPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetCastShadow(bool CastShadow);
|
||||||
|
|
||||||
|
bool GetCastShadow() const
|
||||||
|
{
|
||||||
|
return mCastShadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetName(const QString& Name)
|
||||||
|
{
|
||||||
|
mName = Name;
|
||||||
|
}
|
||||||
|
|
||||||
QString GetName() const override
|
QString GetName() const override
|
||||||
{
|
{
|
||||||
|
@ -198,36 +310,57 @@ public:
|
||||||
|
|
||||||
void CompareBoundingBox(lcVector3& Min, lcVector3& Max);
|
void CompareBoundingBox(lcVector3& Min, lcVector3& Max);
|
||||||
void UpdatePosition(lcStep Step);
|
void UpdatePosition(lcStep Step);
|
||||||
void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance);
|
void MoveSelected(lcStep Step, bool AddKey, const lcVector3& Distance, bool FirstMove);
|
||||||
|
void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame);
|
||||||
bool Setup(int LightIndex);
|
bool Setup(int LightIndex);
|
||||||
void CreateName(const lcArray<lcLight*>& Lights);
|
void CreateName(const lcArray<lcLight*>& Lights);
|
||||||
|
|
||||||
// Temporary parameters
|
lcMatrix44 mWorldMatrix;
|
||||||
lcMatrix44 mWorldLight;
|
|
||||||
lcVector3 mPosition;
|
|
||||||
lcVector3 mTargetPosition;
|
|
||||||
lcVector4 mAmbientColor;
|
|
||||||
lcVector4 mDiffuseColor;
|
|
||||||
lcVector4 mSpecularColor;
|
|
||||||
lcVector3 mAttenuation;
|
|
||||||
float mSpotCutoff;
|
|
||||||
float mSpotExponent;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
lcObjectKeyArray<lcVector3> mPositionKeys;
|
void UpdateLightType();
|
||||||
lcObjectKeyArray<lcVector3> mTargetPositionKeys;
|
|
||||||
lcObjectKeyArray<lcVector4> mAmbientColorKeys;
|
|
||||||
lcObjectKeyArray<lcVector4> mDiffuseColorKeys;
|
|
||||||
lcObjectKeyArray<lcVector4> mSpecularColorKeys;
|
|
||||||
lcObjectKeyArray<lcVector3> mAttenuationKeys;
|
|
||||||
lcObjectKeyArray<float> mSpotCutoffKeys;
|
|
||||||
lcObjectKeyArray<float> mSpotExponentKeys;
|
|
||||||
|
|
||||||
void Initialize(const lcVector3& Position, const lcVector3& TargetPosition);
|
|
||||||
|
|
||||||
void DrawPointLight(lcContext* Context) const;
|
void DrawPointLight(lcContext* Context) const;
|
||||||
void DrawSpotLight(lcContext* Context) const;
|
void DrawSpotLight(lcContext* Context) const;
|
||||||
|
void DrawDirectionalLight(lcContext* Context) const;
|
||||||
|
void DrawAreaLight(lcContext* Context) const;
|
||||||
|
|
||||||
|
void SetupLightMatrix(lcContext* Context) const;
|
||||||
|
void DrawSphere(lcContext* Context, const lcVector3& Center, float Radius) const;
|
||||||
|
void DrawCylinder(lcContext* Context, float Radius, float Height) const;
|
||||||
|
void DrawTarget(lcContext* Context) const;
|
||||||
|
void DrawCone(lcContext* Context, float TargetDistance) const;
|
||||||
|
|
||||||
QString mName;
|
QString mName;
|
||||||
quint32 mState;
|
lcLightType mLightType = lcLightType::Point;
|
||||||
|
bool mCastShadow = true;
|
||||||
|
lcVector3 mColor = lcVector3(1.0f, 1.0f, 1.0f);
|
||||||
|
lcVector2 mSize = lcVector2(0.0f, 0.0f);
|
||||||
|
float mPower = 1.0f;
|
||||||
|
float mAttenuationDistance = 0.0f;
|
||||||
|
float mAttenuationPower = 0.0f;
|
||||||
|
float mSpotConeAngle = 80.0f;
|
||||||
|
float mSpotPenumbraAngle = 0.0f;
|
||||||
|
float mSpotTightness = 0.0f;
|
||||||
|
lcLightAreaShape mAreaShape = lcLightAreaShape::Rectangle;
|
||||||
|
lcVector2i mAreaGrid = lcVector2i(2, 2);
|
||||||
|
|
||||||
|
quint32 mState = 0;
|
||||||
|
bool mSelected = false;
|
||||||
|
quint32 mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||||
|
lcVector3 mTargetMovePosition = lcVector3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
lcObjectKeyArray<lcVector3> mPositionKeys;
|
||||||
|
lcObjectKeyArray<lcMatrix33> mRotationKeys;
|
||||||
|
lcObjectKeyArray<lcVector3> mColorKeys;
|
||||||
|
lcObjectKeyArray<lcVector2> mSizeKeys;
|
||||||
|
lcObjectKeyArray<float> mPowerKeys;
|
||||||
|
lcObjectKeyArray<float> mAttenuationDistanceKeys;
|
||||||
|
lcObjectKeyArray<float> mAttenuationPowerKeys;
|
||||||
|
lcObjectKeyArray<float> mSpotConeAngleKeys;
|
||||||
|
lcObjectKeyArray<float> mSpotPenumbraAngleKeys;
|
||||||
|
lcObjectKeyArray<float> mSpotTightnessKeys;
|
||||||
|
lcObjectKeyArray<lcVector2i> mAreaGridKeys;
|
||||||
|
|
||||||
|
static constexpr float mTargetDistance = 50.0f;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,23 @@
|
||||||
#include "lc_global.h"
|
#include "lc_global.h"
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
|
#define LC_OBJECT_ATTRIBUTE(T) \
|
||||||
|
template void lcObjectKeyArray<T>::SaveKeysLDraw(QTextStream& Stream, const char* ObjectName, const char* VariableName) const; \
|
||||||
|
template void lcObjectKeyArray<T>::LoadKeysLDraw(QTextStream& Stream); \
|
||||||
|
template const T& lcObjectKeyArray<T>::CalculateKey(lcStep Step) const; \
|
||||||
|
template void lcObjectKeyArray<T>::ChangeKey(const T& Value, lcStep Step, bool AddKey); \
|
||||||
|
template void lcObjectKeyArray<T>::InsertTime(lcStep Start, lcStep Time); \
|
||||||
|
template void lcObjectKeyArray<T>::RemoveTime(lcStep Start, lcStep Time); \
|
||||||
|
template void lcObject::SaveAttribute<T>(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const; \
|
||||||
|
template bool lcObject::LoadAttribute<T>(QTextStream& Stream, const QString& Token, T& Variable, lcObjectKeyArray<T>& Keys, const char* VariableName)
|
||||||
|
|
||||||
|
LC_OBJECT_ATTRIBUTE(float);
|
||||||
|
LC_OBJECT_ATTRIBUTE(lcVector2i);
|
||||||
|
LC_OBJECT_ATTRIBUTE(lcVector2);
|
||||||
|
LC_OBJECT_ATTRIBUTE(lcVector3);
|
||||||
|
LC_OBJECT_ATTRIBUTE(lcVector4);
|
||||||
|
LC_OBJECT_ATTRIBUTE(lcMatrix33);
|
||||||
|
|
||||||
lcObject::lcObject(lcObjectType ObjectType)
|
lcObject::lcObject(lcObjectType ObjectType)
|
||||||
: mObjectType(ObjectType)
|
: mObjectType(ObjectType)
|
||||||
{
|
{
|
||||||
|
@ -10,45 +27,32 @@ lcObject::~lcObject()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template void lcObjectKeyArray<float>::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const;
|
|
||||||
template void lcObjectKeyArray<float>::LoadKeysLDraw(QTextStream& Stream);
|
|
||||||
template const float& lcObjectKeyArray<float>::CalculateKey(lcStep Step) const;
|
|
||||||
template void lcObjectKeyArray<float>::ChangeKey(const float& Value, lcStep Step, bool AddKey);
|
|
||||||
template void lcObjectKeyArray<float>::InsertTime(lcStep Start, lcStep Time);
|
|
||||||
template void lcObjectKeyArray<float>::RemoveTime(lcStep Start, lcStep Time);
|
|
||||||
|
|
||||||
template void lcObjectKeyArray<lcVector3>::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const;
|
|
||||||
template void lcObjectKeyArray<lcVector3>::LoadKeysLDraw(QTextStream& Stream);
|
|
||||||
template const lcVector3& lcObjectKeyArray<lcVector3>::CalculateKey(lcStep Step) const;
|
|
||||||
template void lcObjectKeyArray<lcVector3>::ChangeKey(const lcVector3& Value, lcStep Step, bool AddKey);
|
|
||||||
template void lcObjectKeyArray<lcVector3>::InsertTime(lcStep Start, lcStep Time);
|
|
||||||
template void lcObjectKeyArray<lcVector3>::RemoveTime(lcStep Start, lcStep Time);
|
|
||||||
|
|
||||||
template void lcObjectKeyArray<lcVector4>::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const;
|
|
||||||
template void lcObjectKeyArray<lcVector4>::LoadKeysLDraw(QTextStream& Stream);
|
|
||||||
template const lcVector4& lcObjectKeyArray<lcVector4>::CalculateKey(lcStep Step) const;
|
|
||||||
template void lcObjectKeyArray<lcVector4>::ChangeKey(const lcVector4& Value, lcStep Step, bool AddKey);
|
|
||||||
template void lcObjectKeyArray<lcVector4>::InsertTime(lcStep Start, lcStep Time);
|
|
||||||
template void lcObjectKeyArray<lcVector4>::RemoveTime(lcStep Start, lcStep Time);
|
|
||||||
|
|
||||||
template void lcObjectKeyArray<lcMatrix33>::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const;
|
|
||||||
template void lcObjectKeyArray<lcMatrix33>::LoadKeysLDraw(QTextStream& Stream);
|
|
||||||
template const lcMatrix33& lcObjectKeyArray<lcMatrix33>::CalculateKey(lcStep Step) const;
|
|
||||||
template void lcObjectKeyArray<lcMatrix33>::ChangeKey(const lcMatrix33& Value, lcStep Step, bool AddKey);
|
|
||||||
template void lcObjectKeyArray<lcMatrix33>::InsertTime(lcStep Start, lcStep Time);
|
|
||||||
template void lcObjectKeyArray<lcMatrix33>::RemoveTime(lcStep Start, lcStep Time);
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void lcObjectKeyArray<T>::SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const
|
static void SaveFloatValue(QTextStream& Stream, const T& Value)
|
||||||
{
|
{
|
||||||
constexpr int Count = sizeof(T) / sizeof(float);
|
constexpr int Count = sizeof(T) / sizeof(float);
|
||||||
|
|
||||||
|
for (int ValueIndex = 0; ValueIndex < Count; ValueIndex++)
|
||||||
|
Stream << ((const float*)&Value)[ValueIndex] << ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void LoadFloatValue(QTextStream& Stream, T& Value)
|
||||||
|
{
|
||||||
|
constexpr int Count = sizeof(T) / sizeof(float);
|
||||||
|
|
||||||
|
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
|
||||||
|
Stream >> ((float*)&Value)[ValueIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void lcObjectKeyArray<T>::SaveKeysLDraw(QTextStream& Stream, const char* ObjectName, const char* VariableName) const
|
||||||
|
{
|
||||||
for (const lcObjectKey<T>& Key : mKeys)
|
for (const lcObjectKey<T>& Key : mKeys)
|
||||||
{
|
{
|
||||||
Stream << QLatin1String("0 !LEOCAD ") << KeyName << Key.Step << ' ';
|
Stream << QLatin1String("0 !LEOCAD ") << ObjectName << ' ' << VariableName << "_KEY " << Key.Step << ' ';
|
||||||
|
|
||||||
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
|
SaveFloatValue(Stream, Key.Value);
|
||||||
Stream << ((float*)&Key.Value)[ValueIdx] << ' ';
|
|
||||||
|
|
||||||
Stream << QLatin1String("\r\n");
|
Stream << QLatin1String("\r\n");
|
||||||
}
|
}
|
||||||
|
@ -168,3 +172,39 @@ void lcObjectKeyArray<T>::RemoveTime(lcStep Start, lcStep Time)
|
||||||
KeyIt++;
|
KeyIt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void lcObject::SaveAttribute(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const
|
||||||
|
{
|
||||||
|
if (Keys.GetSize() == 1)
|
||||||
|
{
|
||||||
|
Stream << QLatin1String("0 !LEOCAD ") << ObjectName << ' ' << VariableName << ' ';
|
||||||
|
|
||||||
|
SaveFloatValue(Stream, Variable);
|
||||||
|
|
||||||
|
Stream << QLatin1String("\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Keys.SaveKeysLDraw(Stream, ObjectName, VariableName);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool lcObject::LoadAttribute(QTextStream& Stream, const QString& Token, T& Variable, lcObjectKeyArray<T>& Keys, const char* VariableName)
|
||||||
|
{
|
||||||
|
if (Token == VariableName)
|
||||||
|
{
|
||||||
|
LoadFloatValue(Stream, Variable);
|
||||||
|
Keys.ChangeKey(Variable, 1, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Token.endsWith(QLatin1String("_KEY")) && Token.leftRef(Token.size() - 4) == VariableName)
|
||||||
|
{
|
||||||
|
Keys.LoadKeysLDraw(Stream);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
mKeys.clear();
|
mKeys.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const;
|
void SaveKeysLDraw(QTextStream& Stream, const char* ObjectName, const char* VariableName) const;
|
||||||
void LoadKeysLDraw(QTextStream& Stream);
|
void LoadKeysLDraw(QTextStream& Stream);
|
||||||
const T& CalculateKey(lcStep Step) const;
|
const T& CalculateKey(lcStep Step) const;
|
||||||
void ChangeKey(const T& Value, lcStep Step, bool AddKey);
|
void ChangeKey(const T& Value, lcStep Step, bool AddKey);
|
||||||
|
@ -79,15 +79,18 @@ struct lcObjectBoxTest
|
||||||
lcArray<lcObject*> Objects;
|
lcArray<lcObject*> Objects;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LC_OBJECT_TRANSFORM_MOVE_X 0x001
|
#define LC_OBJECT_TRANSFORM_MOVE_X 0x001
|
||||||
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
|
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
|
||||||
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
|
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
|
||||||
#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010
|
#define LC_OBJECT_TRANSFORM_MOVE_XYZ (LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z)
|
||||||
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
|
#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010
|
||||||
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
|
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
|
||||||
#define LC_OBJECT_TRANSFORM_SCALE_X 0x100
|
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
|
||||||
#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200
|
#define LC_OBJECT_TRANSFORM_ROTATE_XYZ (LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z)
|
||||||
#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400
|
#define LC_OBJECT_TRANSFORM_SCALE_X 0x100
|
||||||
|
#define LC_OBJECT_TRANSFORM_SCALE_Y 0x200
|
||||||
|
#define LC_OBJECT_TRANSFORM_SCALE_Z 0x400
|
||||||
|
#define LC_OBJECT_TRANSFORM_SCALE_XYZ (LC_OBJECT_TRANSFORM_SCALE_X | LC_OBJECT_TRANSFORM_SCALE_Y | LC_OBJECT_TRANSFORM_SCALE_Z)
|
||||||
|
|
||||||
class lcObject
|
class lcObject
|
||||||
{
|
{
|
||||||
|
@ -138,7 +141,12 @@ public:
|
||||||
virtual void RemoveKeyFrames() = 0;
|
virtual void RemoveKeyFrames() = 0;
|
||||||
virtual QString GetName() const = 0;
|
virtual QString GetName() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<typename T>
|
||||||
|
void SaveAttribute(QTextStream& Stream, const T& Variable, const lcObjectKeyArray<T>& Keys, const char* ObjectName, const char* VariableName) const;
|
||||||
|
template<typename T>
|
||||||
|
bool LoadAttribute(QTextStream& Stream, const QString& Token, T& Variable, lcObjectKeyArray<T>& Keys, const char* VariableName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lcObjectType mObjectType;
|
lcObjectType mObjectType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -125,10 +125,10 @@ void lcPiece::SaveLDraw(QTextStream& Stream) const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPositionKeys.GetSize() > 1)
|
if (mPositionKeys.GetSize() > 1)
|
||||||
mPositionKeys.SaveKeysLDraw(Stream, "PIECE POSITION_KEY ");
|
mPositionKeys.SaveKeysLDraw(Stream, "PIECE", "POSITION");
|
||||||
|
|
||||||
if (mRotationKeys.GetSize() > 1)
|
if (mRotationKeys.GetSize() > 1)
|
||||||
mRotationKeys.SaveKeysLDraw(Stream, "PIECE ROTATION_KEY ");
|
mRotationKeys.SaveKeysLDraw(Stream, "PIECE", "ROTATION");
|
||||||
|
|
||||||
Stream << "1 " << mColorCode << ' ';
|
Stream << "1 " << mColorCode << ' ';
|
||||||
|
|
||||||
|
@ -835,12 +835,10 @@ void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix)
|
||||||
|
|
||||||
quint32 lcPiece::GetAllowedTransforms() const
|
quint32 lcPiece::GetAllowedTransforms() const
|
||||||
{
|
{
|
||||||
constexpr quint32 Move = LC_OBJECT_TRANSFORM_MOVE_X | LC_OBJECT_TRANSFORM_MOVE_Y | LC_OBJECT_TRANSFORM_MOVE_Z;
|
|
||||||
constexpr quint32 Rotate = LC_OBJECT_TRANSFORM_ROTATE_X | LC_OBJECT_TRANSFORM_ROTATE_Y | LC_OBJECT_TRANSFORM_ROTATE_Z;
|
|
||||||
const quint32 Section = GetFocusSection();
|
const quint32 Section = GetFocusSection();
|
||||||
|
|
||||||
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
|
if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID)
|
||||||
return Move | Rotate;
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ;
|
||||||
|
|
||||||
const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
|
const lcSynthInfo* SynthInfo = mPieceInfo->GetSynthInfo();
|
||||||
|
|
||||||
|
@ -850,10 +848,10 @@ quint32 lcPiece::GetAllowedTransforms() const
|
||||||
return LC_OBJECT_TRANSFORM_MOVE_Z;
|
return LC_OBJECT_TRANSFORM_MOVE_Z;
|
||||||
|
|
||||||
if (SynthInfo->IsCurve())
|
if (SynthInfo->IsCurve())
|
||||||
return Move | Rotate | LC_OBJECT_TRANSFORM_SCALE_X;
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ | LC_OBJECT_TRANSFORM_ROTATE_XYZ | LC_OBJECT_TRANSFORM_SCALE_X;
|
||||||
|
|
||||||
if (SynthInfo->IsNondirectional())
|
if (SynthInfo->IsNondirectional())
|
||||||
return Move;
|
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
void SetSelected(bool Selected) override
|
void SetSelected(bool Selected) override
|
||||||
{
|
{
|
||||||
mSelected = Selected;
|
mSelected = Selected;
|
||||||
|
|
||||||
if (!Selected)
|
if (!Selected)
|
||||||
mFocusedSection = LC_PIECE_SECTION_INVALID;
|
mFocusedSection = LC_PIECE_SECTION_INVALID;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +58,7 @@ public:
|
||||||
Q_UNUSED(Section);
|
Q_UNUSED(Section);
|
||||||
|
|
||||||
mSelected = Selected;
|
mSelected = Selected;
|
||||||
|
|
||||||
if (!Selected)
|
if (!Selected)
|
||||||
mFocusedSection = LC_PIECE_SECTION_INVALID;
|
mFocusedSection = LC_PIECE_SECTION_INVALID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "lc_instructions.h"
|
#include "lc_instructions.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "light.h"
|
||||||
#include "lc_mainwindow.h"
|
#include "lc_mainwindow.h"
|
||||||
#include "lc_view.h"
|
#include "lc_view.h"
|
||||||
#include "lc_library.h"
|
#include "lc_library.h"
|
||||||
|
@ -1828,15 +1829,6 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
POVFile.WriteLine("#version 3.7;\n\nglobal_settings {\n assumed_gamma 1.0\n}\n\n");
|
|
||||||
|
|
||||||
char Line[1024];
|
|
||||||
|
|
||||||
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
|
||||||
std::map<const PieceInfo*, std::pair<char[LC_PIECE_NAME_LEN + 1], int>> PieceTable;
|
|
||||||
size_t NumColors = gColorList.size();
|
|
||||||
std::vector<std::array<char, LC_MAX_COLOR_NAME>> ColorTable(NumColors);
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
LGEO_PIECE_LGEO = 0x01,
|
LGEO_PIECE_LGEO = 0x01,
|
||||||
|
@ -1855,10 +1847,402 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
LGEO_COLOR_GLITTER = 0x40
|
LGEO_COLOR_GLITTER = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
QString LGEOPath; // todo: load lgeo from registry and make sure it still works
|
char Line[1024];
|
||||||
|
|
||||||
if (!LGEOPath.isEmpty())
|
sprintf(Line, "// Generated By: LeoCAD %s\n// LDraw File: %s\n// Date: %s\n\n",
|
||||||
|
LC_VERSION_TEXT,
|
||||||
|
mModels[0]->GetProperties().mFileName.toLatin1().constData(),
|
||||||
|
QDateTime::currentDateTime().toString(Qt::ISODate).toLatin1().constData());
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
POVFile.WriteLine("#version 3.7;\n\n");
|
||||||
|
|
||||||
|
POVFile.WriteLine("global_settings { assumed_gamma 1.0 }\n\n");
|
||||||
|
|
||||||
|
lcPiecesLibrary* Library = lcGetPiecesLibrary();
|
||||||
|
std::map<const PieceInfo*, std::pair<char[LC_PIECE_NAME_LEN + 1], int>> PieceTable;
|
||||||
|
size_t NumColors = gColorList.size();
|
||||||
|
std::vector<std::array<char, LC_MAX_COLOR_NAME>> LgeoColorTable(NumColors);
|
||||||
|
std::vector<std::array<char, LC_MAX_COLOR_NAME>> ColorTable(NumColors);
|
||||||
|
|
||||||
|
const lcArray<lcLight*> Lights = gMainWindow->GetActiveModel()->GetLights();
|
||||||
|
const lcCamera* Camera = gMainWindow->GetActiveView()->GetCamera();
|
||||||
|
const QString CameraName = QString(Camera->GetName()).replace(" ","_");
|
||||||
|
const lcVector3& Position = Camera->mPosition;
|
||||||
|
const lcVector3& Target = Camera->mTargetPosition;
|
||||||
|
const lcVector3& Up = Camera->mUpVector;
|
||||||
|
const lcVector3 BackgroundColor = lcVector3FromColor(lcGetPreferences().mBackgroundSolidColor);
|
||||||
|
const lcPOVRayOptions& POVRayOptions = mModels[0]->GetPOVRayOptions();
|
||||||
|
const QString TopModelName = QString("LC_%1").arg(QString(mModels[0]->GetFileName()).replace(" ","_").replace(".","_dot_"));
|
||||||
|
const QString LGEOPath = lcGetProfileString(LC_PROFILE_POVRAY_LGEO_PATH);
|
||||||
|
const bool UseLGEO = POVRayOptions.UseLGEO && !LGEOPath.isEmpty();
|
||||||
|
const int TopModelColorCode = 7;
|
||||||
|
QStringList ColorMacros, MaterialColors;
|
||||||
|
|
||||||
|
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||||
|
lcVector3 Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||||
|
|
||||||
|
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||||
{
|
{
|
||||||
|
lcVector3 Points[8];
|
||||||
|
|
||||||
|
lcGetBoxCorners(ModelPart.Info->GetBoundingBox(), Points);
|
||||||
|
|
||||||
|
for (int PointIdx = 0; PointIdx < 8; PointIdx++)
|
||||||
|
{
|
||||||
|
lcVector3 Point = lcMul31(Points[PointIdx], ModelPart.WorldMatrix);
|
||||||
|
|
||||||
|
Min = lcMin(Point, Min);
|
||||||
|
Max = lcMax(Point, Max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lcVector3 Center = (Min + Max) / 2.0f;
|
||||||
|
float Radius = (Max - Center).Length() / 25.0f;
|
||||||
|
Center = lcVector3(Center[1], Center[0], Center[2]) / 25.0f;
|
||||||
|
|
||||||
|
lcVector3 FloorColor = POVRayOptions.FloorColor;
|
||||||
|
float FloorAmbient = POVRayOptions.FloorAmbient;
|
||||||
|
float FloorDiffuse = POVRayOptions.FloorDiffuse;
|
||||||
|
char FloorLocation[32];
|
||||||
|
char FloorAxis[16];
|
||||||
|
if (POVRayOptions.FloorAxis == 0)
|
||||||
|
{
|
||||||
|
sprintf(FloorAxis, "x");
|
||||||
|
sprintf(FloorLocation, "MaxX");
|
||||||
|
}
|
||||||
|
else if (POVRayOptions.FloorAxis == 1)
|
||||||
|
{
|
||||||
|
sprintf(FloorAxis, "y");
|
||||||
|
sprintf(FloorLocation, "MaxY");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(FloorAxis, "z");
|
||||||
|
sprintf(FloorLocation, "MaxZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const lcLight* Light : Lights)
|
||||||
|
{
|
||||||
|
if (Light->GetLightType() == lcLightType::Area)
|
||||||
|
{
|
||||||
|
if (FloorColor == lcVector3(0.8f,0.8f,0.8f))
|
||||||
|
FloorColor = {1.0f,1.0f,1.0f};
|
||||||
|
if (FloorAmbient == 0.4f)
|
||||||
|
FloorAmbient = 0.0f;
|
||||||
|
if (FloorDiffuse == 0.4f)
|
||||||
|
FloorDiffuse = 0.9f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!POVRayOptions.HeaderIncludeFile.isEmpty())
|
||||||
|
{
|
||||||
|
sprintf(Line, "#include \"%s\"\n\n", POVRayOptions.HeaderIncludeFile.toLatin1().constData());
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (MinX) #declare MinX = %g; #end\n"
|
||||||
|
"#ifndef (MinY) #declare MinY = %g; #end\n"
|
||||||
|
"#ifndef (MinZ) #declare MinZ = %g; #end\n"
|
||||||
|
"#ifndef (MaxX) #declare MaxX = %g; #end\n"
|
||||||
|
"#ifndef (MaxY) #declare MaxY = %g; #end\n"
|
||||||
|
"#ifndef (MaxZ) #declare MaxZ = %g; #end\n"
|
||||||
|
"#ifndef (CenterX) #declare CenterX = %g; #end\n"
|
||||||
|
"#ifndef (CenterY) #declare CenterY = %g; #end\n"
|
||||||
|
"#ifndef (CenterZ) #declare CenterZ = %g; #end\n"
|
||||||
|
"#ifndef (Center) #declare Center = <CenterX,CenterY,CenterZ>; #end\n"
|
||||||
|
"#ifndef (Radius) #declare Radius = %g; #end\n",
|
||||||
|
Min[0], Min[1], Min[2], Max[0], -Max[1], Max[2], Center[0], Center[1], Center[2], Radius);
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (CameraSky) #declare CameraSky = <%g,%g,%g>; #end\n"
|
||||||
|
"#ifndef (CameraLocation) #declare CameraLocation = <%g, %g, %g>; #end\n"
|
||||||
|
"#ifndef (CameraTarget) #declare CameraTarget = <%g, %g, %g>; #end\n"
|
||||||
|
"#ifndef (CameraAngle) #declare CameraAngle = %g; #end\n",
|
||||||
|
Up[1], Up[0], Up[2], Position[1] / 25.0f, Position[0] / 25.0f, Position[2] / 25.0f, Target[1] / 25.0f, Target[0] / 25.0f, Target[2] / 25.0f, Camera->m_fovy);
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (BackgroundColor) #declare BackgroundColor = <%1g, %1g, %1g>; #end\n"
|
||||||
|
"#ifndef (Background) #declare Background = %s; #end\n",
|
||||||
|
BackgroundColor[0], BackgroundColor[1], BackgroundColor[2], (POVRayOptions.ExcludeBackground ? "false" : "true"));
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (FloorAxis) #declare FloorAxis = %s; #end\n"
|
||||||
|
"#ifndef (FloorLocation) #declare FloorLocation = %s; #end\n"
|
||||||
|
"#ifndef (FloorColor) #declare FloorColor = <%1g, %1g, %1g>; #end\n"
|
||||||
|
"#ifndef (FloorAmbient) #declare FloorAmbient = %1g; #end\n"
|
||||||
|
"#ifndef (FloorDiffuse) #declare FloorDiffuse = %1g; #end\n"
|
||||||
|
"#ifndef (Floor) #declare Floor = %s; #end\n",
|
||||||
|
FloorAxis, FloorLocation, FloorColor[0], FloorColor[1], FloorColor[2], FloorAmbient, FloorDiffuse, (POVRayOptions.ExcludeFloor ? "false" : "true"));
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (Ambient) #declare Ambient = 0.4; #end\n"
|
||||||
|
"#ifndef (Diffuse) #declare Diffuse = 0.4; #end\n"
|
||||||
|
"#ifndef (Reflection) #declare Reflection = 0.08; #end\n"
|
||||||
|
"#ifndef (Phong) #declare Phong = 0.5; #end\n"
|
||||||
|
"#ifndef (PhongSize) #declare PhongSize = 40; #end\n"
|
||||||
|
"#ifndef (TransReflection) #declare TransReflection = 0.2; #end\n"
|
||||||
|
"#ifndef (TransFilter) #declare TransFilter = 0.85; #end\n"
|
||||||
|
"#ifndef (TransIoR) #declare TransIoR = 1.25; #end\n"
|
||||||
|
"#ifndef (RubberReflection) #declare RubberReflection = 0; #end\n"
|
||||||
|
"#ifndef (RubberPhong) #declare RubberPhong = 0.1; #end\n"
|
||||||
|
"#ifndef (RubberPhongS) #declare RubberPhongS = 10; #end\n"
|
||||||
|
"#ifndef (ChromeReflection) #declare ChromeReflection = 0.85; #end\n"
|
||||||
|
"#ifndef (ChromeBrilliance) #declare ChromeBrilliance = 5; #end\n"
|
||||||
|
"#ifndef (ChromeSpecular) #declare ChromeSpecular = 0.8; #end\n"
|
||||||
|
"#ifndef (ChromeRough) #declare ChromeRough = 0.01; #end\n"
|
||||||
|
"#ifndef (OpaqueNormal) #declare OpaqueNormal = normal { bumps 0.001 scale 0.5 }; #end\n"
|
||||||
|
"#ifndef (TransNormal) #declare TransNormal = normal { bumps 0.001 scale 0.5 }; #end\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (Quality) #declare Quality = 3; #end\n"
|
||||||
|
"#ifndef (Studs) #declare Studs = 1; #end\n"
|
||||||
|
"#ifndef (LgeoLibrary) #declare LgeoLibrary = %s; #end\n"
|
||||||
|
"#ifndef (ModelReflection) #declare ModelReflection = %i; #end\n"
|
||||||
|
"#ifndef (ModelShadow) #declare ModelShadow = %i; #end\n\n",
|
||||||
|
(POVRayOptions.UseLGEO ? "true" : "false"), (POVRayOptions.NoReflection ? 0 : 1), (POVRayOptions.NoShadow ? 0 : 1));
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (SkipWriteLightMacro)\n"
|
||||||
|
"#macro WriteLight(Type, Shadowless, Location, Target, Color, Power, FadeDistance, FadePower, SpotRadius, SpotFalloff, SpotTightness, AreaCircle, AreaWidth, AreaHeight, AreaRows, AreaColumns)\n"
|
||||||
|
" #local PointLight = %i;\n"
|
||||||
|
" #local Spotlight = %i;\n"
|
||||||
|
" #local DirectionalLight = %i;\n"
|
||||||
|
" #local AreaLight = %i;\n"
|
||||||
|
" light_source {\n"
|
||||||
|
" Location\n"
|
||||||
|
" color rgb Color*Power\n"
|
||||||
|
" #if (Shadowless > 0)\n"
|
||||||
|
" shadowless\n"
|
||||||
|
" #end\n"
|
||||||
|
" #if (FadeDistance > 0)\n"
|
||||||
|
" fade_distance FadeDistance\n"
|
||||||
|
" #end\n"
|
||||||
|
" #if (FadePower > 0)\n"
|
||||||
|
" fade_power FadePower\n"
|
||||||
|
" #end\n"
|
||||||
|
" #if (Type = Spotlight)\n"
|
||||||
|
" spotlight\n"
|
||||||
|
" radius SpotRadius\n"
|
||||||
|
" falloff SpotFalloff\n"
|
||||||
|
" tightness SpotTightness\n"
|
||||||
|
" point_at Target\n"
|
||||||
|
" #elseif (Type = DirectionalLight)\n"
|
||||||
|
" parallel\n"
|
||||||
|
" point_at Target\n"
|
||||||
|
" #elseif (Type = AreaLight)\n"
|
||||||
|
" area_light AreaWidth, AreaHeight, AreaRows, AreaColumns\n"
|
||||||
|
" jitter\n"
|
||||||
|
" #if (AreaCircle > 0 & AreaWidth > 2 & AreaHeight > 2 & AreaRows > 1 & AreaColumns > 1 )\n"
|
||||||
|
" circular \n"
|
||||||
|
" #if (AreaWidth = AreaHeight & AreaRows = AreaColumns)\n"
|
||||||
|
" orient\n"
|
||||||
|
" #end\n"
|
||||||
|
" #end\n"
|
||||||
|
" #end\n"
|
||||||
|
" }\n"
|
||||||
|
"#end\n"
|
||||||
|
"#end\n\n",
|
||||||
|
lcLightType::Point, lcLightType::Spot, lcLightType::Directional, lcLightType::Area);
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||||
|
{
|
||||||
|
int ColorIdx = ModelPart.ColorIndex;
|
||||||
|
|
||||||
|
if (lcIsColorTranslucent(ColorIdx))
|
||||||
|
{
|
||||||
|
if (!ColorMacros.contains("TranslucentColor"))
|
||||||
|
{
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (SkipTranslucentColorMacro)\n"
|
||||||
|
"#macro TranslucentColor(r, g, b, f)\n"
|
||||||
|
" material {\n"
|
||||||
|
" texture {\n"
|
||||||
|
" pigment { srgbf <r,g,b,f> }\n"
|
||||||
|
" finish { emission 0 ambient Ambient diffuse Diffuse }\n"
|
||||||
|
" finish { phong Phong phong_size PhongSize reflection TransReflection }\n"
|
||||||
|
" normal { TransNormal }\n"
|
||||||
|
" }\n"
|
||||||
|
" interior { ior TransIoR }\n"
|
||||||
|
" }\n"
|
||||||
|
"#end\n"
|
||||||
|
"#end\n\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
ColorMacros.append("TranslucentColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lcIsColorChrome(ColorIdx))
|
||||||
|
{
|
||||||
|
if (!ColorMacros.contains("ChromeColor"))
|
||||||
|
{
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (SkipChromeColorMacro)\n"
|
||||||
|
"#macro ChromeColor(r, g, b)\n"
|
||||||
|
"#if (LgeoLibrary) material { #end\n"
|
||||||
|
" texture {\n"
|
||||||
|
" pigment { srgbf <r,g,b,0> }\n"
|
||||||
|
" finish { emission 0 ambient Ambient diffuse Diffuse }\n"
|
||||||
|
" finish { phong Phong phong_size PhongSize reflection ChromeReflection brilliance ChromeBrilliance metallic specular ChromeSpecular roughness ChromeRough }\n"
|
||||||
|
" }\n"
|
||||||
|
"#if (LgeoLibrary) } #end\n"
|
||||||
|
"#end\n"
|
||||||
|
"#end\n\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
ColorMacros.append("ChromeColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lcIsColorRubber(ColorIdx))
|
||||||
|
{
|
||||||
|
if (!ColorMacros.contains("RubberColor"))
|
||||||
|
{
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (SkipRubberColorMacro)\n"
|
||||||
|
"#macro RubberColor(r, g, b)\n"
|
||||||
|
"#if (LgeoLibrary) material { #end\n"
|
||||||
|
" texture {\n"
|
||||||
|
" pigment { srgbf <r,g,b,0> }\n"
|
||||||
|
" finish { emission 0 ambient Ambient diffuse Diffuse }\n"
|
||||||
|
" finish { phong RubberPhong phong_size RubberPhongS reflection RubberReflection }\n"
|
||||||
|
" }\n"
|
||||||
|
"#if (LgeoLibrary) } #end\n"
|
||||||
|
"#end\n"
|
||||||
|
"#end\n\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
ColorMacros.append("RubberColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!ColorMacros.contains("OpaqueColor"))
|
||||||
|
{
|
||||||
|
sprintf(Line,
|
||||||
|
"#ifndef (SkipOpaqueColorMacro)\n"
|
||||||
|
"#macro OpaqueColor(r, g, b)\n"
|
||||||
|
"#if (LgeoLibrary) material { #end\n"
|
||||||
|
" texture {\n"
|
||||||
|
" pigment { srgbf <r,g,b,0> }\n"
|
||||||
|
" finish { emission 0 ambient Ambient diffuse Diffuse }\n"
|
||||||
|
" finish { phong Phong phong_size PhongSize reflection Reflection }\n"
|
||||||
|
" normal { OpaqueNormal }\n"
|
||||||
|
" }\n"
|
||||||
|
"#if (LgeoLibrary) } #end\n"
|
||||||
|
"#end\n"
|
||||||
|
"#end\n\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
ColorMacros.append("OpaqueColor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(Line, "#if (Background)\n background {\n color rgb BackgroundColor\n }\n#end\n\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
sprintf(Line, "#ifndef (Skip%s)\n camera {\n perspective\n right x * image_width / image_height\n sky CameraSky\n location CameraLocation\n look_at CameraTarget\n angle CameraAngle * image_width / image_height\n }\n#end\n\n",
|
||||||
|
(CameraName.isEmpty() ? "Camera" : CameraName.toLatin1().constData()));
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
lcVector3 AreaX(1.0f, 0.0f, 0.0f), AreaY(0.0f, 1.0f, 0.0f);
|
||||||
|
lcVector2i AreaGrid(1, 1);
|
||||||
|
int AreaCircle = 0, Shadowless = 0;
|
||||||
|
lcLightType LightType = lcLightType::Area;
|
||||||
|
float Power = 0.0f, FadeDistance = 0.0f, FadePower = 0.0f, SpotRadius = 0.0f, SpotFalloff = 0.0f, SpotTightness = 0.0f;
|
||||||
|
|
||||||
|
if (Lights.IsEmpty())
|
||||||
|
{
|
||||||
|
const lcVector3 LightTarget(0.0f, 0.0f, 0.0f), LightColor(1.0f, 1.0f, 1.0f);
|
||||||
|
lcVector3 Location[4];
|
||||||
|
|
||||||
|
Location[0] = {0.0f * Radius + Center[0], -1.5f * Radius + Center[1], -1.5f * Radius + Center[2]};
|
||||||
|
Location[1] = {1.5f * Radius + Center[0], -1.0f * Radius + Center[1], 0.866026f * Radius + Center[2]};
|
||||||
|
Location[2] = {0.0f * Radius + Center[0], -2.0f * Radius + Center[1], 0.0f * Radius + Center[2]};
|
||||||
|
Location[3] = {2.0f * Radius + Center[0], 0.0f * Radius + Center[1], -2.0f * Radius + Center[2]};
|
||||||
|
|
||||||
|
for (int Idx = 0; Idx < 4; Idx++)
|
||||||
|
{
|
||||||
|
Power = Idx < 2 ? 0.75f : 0.5f;
|
||||||
|
sprintf(Line,"#ifndef (SkipLight%i)\nWriteLight(%i, %i, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, %g, %g, %g, %g, %g, %g, %i, <%g, %g, %g>, <%g, %g, %g>, %i, %i)\n#end\n\n",
|
||||||
|
Idx,
|
||||||
|
LightType,
|
||||||
|
Shadowless,
|
||||||
|
Location[Idx][0], Location[Idx][1], Location[Idx][2],
|
||||||
|
LightTarget[0], LightTarget[1], LightTarget[2],
|
||||||
|
LightColor[0], LightColor[1], LightColor[2],
|
||||||
|
Power,
|
||||||
|
FadeDistance, FadePower,
|
||||||
|
SpotRadius, SpotFalloff, SpotTightness,
|
||||||
|
AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], AreaGrid.x, AreaGrid.y);
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const lcLight* Light : Lights)
|
||||||
|
{
|
||||||
|
const lcVector3 LightPosition = Light->GetPosition();
|
||||||
|
const lcVector3 LightTarget = LightPosition + Light->GetDirection();
|
||||||
|
const lcVector3 LightColor = Light->GetColor();
|
||||||
|
const QString LightName = QString(Light->GetName()).replace(" ", "_");
|
||||||
|
LightType = Light->GetLightType();
|
||||||
|
Shadowless = Light->GetCastShadow() ? 0 : 1;
|
||||||
|
Power = Light->GetPower();
|
||||||
|
FadeDistance = Light->GetAttenuationDistance();
|
||||||
|
FadePower = Light->GetAttenuationPower();
|
||||||
|
|
||||||
|
switch (LightType)
|
||||||
|
{
|
||||||
|
case lcLightType::Point:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Spot:
|
||||||
|
SpotFalloff = Light->GetSpotConeAngle() / 2.0f;
|
||||||
|
SpotRadius = SpotFalloff - Light->GetSpotPenumbraAngle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Directional:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Area:
|
||||||
|
AreaCircle = (Light->GetAreaShape() == lcLightAreaShape::Disk || Light->GetAreaShape() == lcLightAreaShape::Ellipse) ? 1 : 0;
|
||||||
|
AreaX = lcVector3(Light->GetWorldMatrix()[0]) * Light->GetSize().x;
|
||||||
|
AreaY = lcVector3(Light->GetWorldMatrix()[1]) * Light->GetSize().y;
|
||||||
|
AreaGrid = Light->GetAreaGrid();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(Line,"#ifndef (Skip%s)\n WriteLight(%i, %i, <%g, %g, %g>, <%g, %g, %g>, <%g, %g, %g>, %g, %g, %g, %g, %g, %g, %i, <%g, %g, %g>, <%g, %g, %g>, %i, %i)\n#end\n\n",
|
||||||
|
LightName.toLatin1().constData(),
|
||||||
|
LightType,
|
||||||
|
Shadowless,
|
||||||
|
LightPosition[1], LightPosition[0], LightPosition[2],
|
||||||
|
LightTarget[1], LightTarget[0], LightTarget[2],
|
||||||
|
LightColor[0], LightColor[1], LightColor[2],
|
||||||
|
Power,
|
||||||
|
FadeDistance, FadePower,
|
||||||
|
SpotRadius, SpotFalloff, SpotTightness,
|
||||||
|
AreaCircle, AreaX[0], AreaX[1], AreaX[2], AreaY[0], AreaY[1], AreaY[2], AreaGrid.x, AreaGrid.y);
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
POVFile.WriteLine("#ifndef (lg_quality) #declare lg_quality = Quality; #end\n\n");
|
||||||
|
|
||||||
|
if (UseLGEO)
|
||||||
|
{
|
||||||
|
memset(Line, 0, 1024);
|
||||||
|
|
||||||
|
POVFile.WriteLine("#ifndef (lg_studs) #declare lg_studs = Studs; #end\n\n");
|
||||||
|
|
||||||
|
POVFile.WriteLine("#if (lg_quality = 3) #declare lg_quality = 4; #end\n\n");
|
||||||
|
|
||||||
|
POVFile.WriteLine("#include \"lg_defs.inc\"\n\n#include \"lg_color.inc\"\n\n");
|
||||||
|
|
||||||
lcDiskFile TableFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_elements.lst")).absoluteFilePath());
|
lcDiskFile TableFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_elements.lst")).absoluteFilePath());
|
||||||
|
|
||||||
if (!TableFile.Open(QIODevice::ReadOnly))
|
if (!TableFile.Open(QIODevice::ReadOnly))
|
||||||
|
@ -1869,6 +2253,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
|
|
||||||
while (TableFile.ReadLine(Line, sizeof(Line)))
|
while (TableFile.ReadLine(Line, sizeof(Line)))
|
||||||
{
|
{
|
||||||
|
|
||||||
char Src[129], Dst[129], Flags[11];
|
char Src[129], Dst[129], Flags[11];
|
||||||
|
|
||||||
if (*Line == ';')
|
if (*Line == ';')
|
||||||
|
@ -1877,20 +2262,22 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
if (sscanf(Line,"%128s%128s%10s", Src, Dst, Flags) != 3)
|
if (sscanf(Line,"%128s%128s%10s", Src, Dst, Flags) != 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strcat(Src, ".dat");
|
strncat(Src, ".dat", 4);
|
||||||
|
|
||||||
PieceInfo* Info = Library->FindPiece(Src, nullptr, false, false);
|
PieceInfo* Info = Library->FindPiece(Src, nullptr, false, false);
|
||||||
if (!Info)
|
if (!Info)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strchr(Flags, 'L'))
|
bool LgeoPartFound = false;
|
||||||
|
|
||||||
|
if ((LgeoPartFound = strchr(Flags, 'L')))
|
||||||
{
|
{
|
||||||
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[Info];
|
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[Info];
|
||||||
Entry.second |= LGEO_PIECE_LGEO;
|
Entry.second |= LGEO_PIECE_LGEO;
|
||||||
sprintf(Entry.first, "lg_%s", Dst);
|
sprintf(Entry.first, "lg_%s", Dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strchr(Flags, 'A'))
|
if (strchr(Flags, 'A') && !LgeoPartFound)
|
||||||
{
|
{
|
||||||
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[Info];
|
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[Info];
|
||||||
Entry.second |= LGEO_PIECE_AR;
|
Entry.second |= LGEO_PIECE_AR;
|
||||||
|
@ -1905,15 +2292,15 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lcDiskFile ColorFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_colors.lst")).absoluteFilePath());
|
lcDiskFile LgeoColorFile(QFileInfo(QDir(LGEOPath), QLatin1String("lg_colors.lst")).absoluteFilePath());
|
||||||
|
|
||||||
if (!ColorFile.Open(QIODevice::ReadOnly))
|
if (!LgeoColorFile.Open(QIODevice::ReadOnly))
|
||||||
{
|
{
|
||||||
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath));
|
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("Could not find LGEO files in folder '%1'.").arg(LGEOPath));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ColorFile.ReadLine(Line, sizeof(Line)))
|
while (LgeoColorFile.ReadLine(Line, sizeof(Line)))
|
||||||
{
|
{
|
||||||
char Name[1024], Flags[1024];
|
char Name[1024], Flags[1024];
|
||||||
int Code;
|
int Code;
|
||||||
|
@ -1924,20 +2311,82 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
if (sscanf(Line,"%d%s%s", &Code, Name, Flags) != 3)
|
if (sscanf(Line,"%d%s%s", &Code, Name, Flags) != 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t Color = lcGetColorIndex(Code);
|
size_t ColorIdx = lcGetColorIndex(Code);
|
||||||
if (Color >= NumColors)
|
if (ColorIdx >= NumColors)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strcpy(ColorTable[Color].data(), Name);
|
strncpy(LgeoColorTable[ColorIdx].data(), Name, LC_MAX_COLOR_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||||
|
{
|
||||||
|
size_t ColorIdx = ModelPart.ColorIndex;
|
||||||
|
|
||||||
|
if (!ColorTable[ColorIdx][0])
|
||||||
|
{
|
||||||
|
lcColor* Color = &gColorList[ColorIdx];
|
||||||
|
|
||||||
|
if (!LgeoColorTable[ColorIdx][0])
|
||||||
|
{
|
||||||
|
sprintf(ColorTable[ColorIdx].data(), "lc_%s", Color->SafeName);
|
||||||
|
|
||||||
|
if (lcIsColorTranslucent(ColorIdx))
|
||||||
|
{
|
||||||
|
if (!UseLGEO && !MaterialColors.contains(ColorTable[ColorIdx].data()))
|
||||||
|
MaterialColors.append(ColorTable[ColorIdx].data());
|
||||||
|
|
||||||
|
sprintf(Line, "#ifndef (lc_%s)\n#declare lc_%s = TranslucentColor(%g, %g, %g, TransFilter)\n#end\n\n",
|
||||||
|
Color->SafeName, Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char MacroName[LC_MAX_COLOR_NAME];
|
||||||
|
if (lcIsColorChrome(ColorIdx))
|
||||||
|
sprintf(MacroName, "Chrome");
|
||||||
|
else if (lcIsColorRubber(ColorIdx))
|
||||||
|
sprintf(MacroName, "Rubber");
|
||||||
|
else
|
||||||
|
sprintf(MacroName, "Opaque");
|
||||||
|
|
||||||
|
sprintf(Line, "#ifndef (lc_%s)\n#declare lc_%s = %sColor(%g, %g, %g)\n#end\n\n",
|
||||||
|
Color->SafeName, Color->SafeName, MacroName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(ColorTable[ColorIdx].data(), "LDXColor%i", Color->Code);
|
||||||
|
|
||||||
|
sprintf(Line,"#ifndef (LDXColor%i) // %s\n#declare LDXColor%i = material { texture { %s } }\n#end\n\n",
|
||||||
|
Color->Code, Color->Name, Color->Code, LgeoColorTable[ColorIdx].data());
|
||||||
|
}
|
||||||
|
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ColorTable[lcGetColorIndex(TopModelColorCode)][0])
|
||||||
|
{
|
||||||
|
size_t ColorIdx = lcGetColorIndex(TopModelColorCode);
|
||||||
|
|
||||||
|
lcColor* Color = &gColorList[ColorIdx];
|
||||||
|
|
||||||
|
sprintf(ColorTable[ColorIdx].data(), "LDXColor%i", Color->Code);
|
||||||
|
|
||||||
|
if (!LgeoColorTable[ColorIdx][0])
|
||||||
|
sprintf(Line, "#ifndef (lc_%s)\n#declare lc_%s = OpaqueColor(%g, %g, %g)\n#end\n\n",
|
||||||
|
Color->SafeName, Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
||||||
|
else
|
||||||
|
sprintf(Line,"#ifndef (LDXColor%i) // %s\n#declare LDXColor%i = material { texture { %s } }\n#end\n\n",
|
||||||
|
Color->Code, Color->Name, Color->Code, LgeoColorTable[ColorIdx].data());
|
||||||
|
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
}
|
||||||
|
|
||||||
std::set<lcMesh*> AddedMeshes;
|
std::set<lcMesh*> AddedMeshes;
|
||||||
|
|
||||||
if (!LGEOPath.isEmpty())
|
if (UseLGEO)
|
||||||
{
|
{
|
||||||
POVFile.WriteLine("#include \"lg_defs.inc\"\n#include \"lg_color.inc\"\n\n");
|
|
||||||
|
|
||||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||||
{
|
{
|
||||||
if (ModelPart.Mesh)
|
if (ModelPart.Mesh)
|
||||||
|
@ -1958,7 +2407,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
const std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = Search->second;
|
const std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = Search->second;
|
||||||
if (Entry.first[0])
|
if (Entry.first[0])
|
||||||
{
|
{
|
||||||
sprintf(Line, "#include \"%s.inc\"\n", Entry.first);
|
sprintf(Line, "#include \"%s.inc\" // %s\n", Entry.first, ModelPart.Info->m_strDescription);
|
||||||
POVFile.WriteLine(Line);
|
POVFile.WriteLine(Line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1966,29 +2415,6 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
POVFile.WriteLine("\n");
|
POVFile.WriteLine("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t ColorIdx = 0; ColorIdx < gColorList.size(); ColorIdx++)
|
|
||||||
{
|
|
||||||
lcColor* Color = &gColorList[ColorIdx];
|
|
||||||
|
|
||||||
if (lcIsColorTranslucent(ColorIdx))
|
|
||||||
{
|
|
||||||
sprintf(Line, "#declare lc_%s = texture { pigment { rgb <%f, %f, %f> filter 0.9 } finish { ambient 0.3 diffuse 0.2 reflection 0.25 phong 0.3 phong_size 60 } }\n",
|
|
||||||
Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(Line, "#declare lc_%s = texture { pigment { rgb <%f, %f, %f> } finish { ambient 0.1 phong 0.2 phong_size 20 } }\n",
|
|
||||||
Color->SafeName, Color->Value[0], Color->Value[1], Color->Value[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
POVFile.WriteLine(Line);
|
|
||||||
|
|
||||||
if (!ColorTable[ColorIdx][0])
|
|
||||||
sprintf(ColorTable[ColorIdx].data(), "lc_%s", Color->SafeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
POVFile.WriteLine("\n");
|
|
||||||
|
|
||||||
std::vector<const char*> ColorTablePointer;
|
std::vector<const char*> ColorTablePointer;
|
||||||
ColorTablePointer.resize(NumColors);
|
ColorTablePointer.resize(NumColors);
|
||||||
for (size_t ColorIdx = 0; ColorIdx < NumColors; ColorIdx++)
|
for (size_t ColorIdx = 0; ColorIdx < NumColors; ColorIdx++)
|
||||||
|
@ -1996,7 +2422,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
|
|
||||||
auto GetMeshName = [](const lcModelPartsEntry& ModelPart, char (&Name)[LC_PIECE_NAME_LEN])
|
auto GetMeshName = [](const lcModelPartsEntry& ModelPart, char (&Name)[LC_PIECE_NAME_LEN])
|
||||||
{
|
{
|
||||||
strcpy(Name, ModelPart.Info->mFileName);
|
strncpy(Name, ModelPart.Info->mFileName, sizeof(Name));
|
||||||
|
|
||||||
for (char* c = Name; *c; c++)
|
for (char* c = Name; *c; c++)
|
||||||
if (*c == '-' || *c == '.')
|
if (*c == '-' || *c == '.')
|
||||||
|
@ -2006,7 +2432,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
{
|
{
|
||||||
char Suffix[32];
|
char Suffix[32];
|
||||||
sprintf(Suffix, "_%p", ModelPart.Mesh);
|
sprintf(Suffix, "_%p", ModelPart.Mesh);
|
||||||
strncat(Name, Suffix, sizeof(Name) - 1);
|
strncat(Name, Suffix, sizeof(Name) - strlen(Name) - 1);
|
||||||
Name[sizeof(Name) - 1] = 0;
|
Name[sizeof(Name) - 1] = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2027,7 +2453,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
if (!ModelPart.Mesh)
|
if (!ModelPart.Mesh)
|
||||||
{
|
{
|
||||||
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[ModelPart.Info];
|
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[ModelPart.Info];
|
||||||
strcpy(Entry.first, "lc_");
|
strncpy(Entry.first, "lc_", 3);
|
||||||
strncat(Entry.first, Name, sizeof(Entry.first) - 1);
|
strncat(Entry.first, Name, sizeof(Entry.first) - 1);
|
||||||
Entry.first[sizeof(Entry.first) - 1] = 0;
|
Entry.first[sizeof(Entry.first) - 1] = 0;
|
||||||
}
|
}
|
||||||
|
@ -2038,65 +2464,30 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
POVFile.WriteLine(Line);
|
POVFile.WriteLine(Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lcCamera* Camera = gMainWindow->GetActiveView()->GetCamera();
|
sprintf(Line, "#declare %s = union {\n", TopModelName.toLatin1().constData());
|
||||||
const lcVector3& Position = Camera->mPosition;
|
|
||||||
const lcVector3& Target = Camera->mTargetPosition;
|
|
||||||
const lcVector3& Up = Camera->mUpVector;
|
|
||||||
|
|
||||||
sprintf(Line, "camera {\n perspective\n right x * image_width / image_height\n sky<%1g,%1g,%1g>\n location <%1g, %1g, %1g>\n look_at <%1g, %1g, %1g>\n angle %.0f * image_width / image_height\n}\n\n",
|
|
||||||
Up[1], Up[0], Up[2], Position[1] / 25.0f, Position[0] / 25.0f, Position[2] / 25.0f, Target[1] / 25.0f, Target[0] / 25.0f, Target[2] / 25.0f, Camera->m_fovy);
|
|
||||||
POVFile.WriteLine(Line);
|
|
||||||
lcVector3 BackgroundColor = lcVector3FromColor(lcGetPreferences().mBackgroundSolidColor);
|
|
||||||
sprintf(Line, "background { color rgb <%1g, %1g, %1g> }\n\n", BackgroundColor[0], BackgroundColor[1], BackgroundColor[2]);
|
|
||||||
POVFile.WriteLine(Line);
|
|
||||||
|
|
||||||
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX);
|
|
||||||
lcVector3 Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
|
|
||||||
|
|
||||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
|
||||||
{
|
|
||||||
lcVector3 Points[8];
|
|
||||||
|
|
||||||
lcGetBoxCorners(ModelPart.Info->GetBoundingBox(), Points);
|
|
||||||
|
|
||||||
for (int PointIdx = 0; PointIdx < 8; PointIdx++)
|
|
||||||
{
|
|
||||||
lcVector3 Point = lcMul31(Points[PointIdx], ModelPart.WorldMatrix);
|
|
||||||
|
|
||||||
Min = lcMin(Point, Min);
|
|
||||||
Max = lcMax(Point, Max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lcVector3 Center = (Min + Max) / 2.0f;
|
|
||||||
float Radius = (Max - Center).Length() / 25.0f;
|
|
||||||
Center = lcVector3(Center[1], Center[0], Center[2]) / 25.0f;
|
|
||||||
|
|
||||||
sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.75\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 0.0f * Radius + Center.x, -1.5f * Radius + Center.y, -1.5f * Radius + Center.z);
|
|
||||||
POVFile.WriteLine(Line);
|
|
||||||
sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.75\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 1.5f * Radius + Center.x, -1.0f * Radius + Center.y, 0.866026f * Radius + Center.z);
|
|
||||||
POVFile.WriteLine(Line);
|
|
||||||
sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.5\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 0.0f * Radius + Center.x, -2.0f * Radius + Center.y, 0.0f * Radius + Center.z);
|
|
||||||
POVFile.WriteLine(Line);
|
|
||||||
sprintf(Line, "light_source{ <%f, %f, %f>\n color rgb 0.5\n area_light 200, 200, 10, 10\n jitter\n}\n\n", 2.0f * Radius + Center.x, 0.0f * Radius + Center.y, -2.0f * Radius + Center.z);
|
|
||||||
POVFile.WriteLine(Line);
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||||
{
|
{
|
||||||
int Color = ModelPart.ColorIndex;
|
int ColorIdx = ModelPart.ColorIndex;
|
||||||
const char* Suffix = lcIsColorTranslucent(Color) ? "_clear" : "";
|
const char* Suffix = lcIsColorTranslucent(ColorIdx) ? "_clear" : "";
|
||||||
const float* f = ModelPart.WorldMatrix;
|
const float* f = ModelPart.WorldMatrix;
|
||||||
|
char Modifier[32];
|
||||||
|
if (UseLGEO || MaterialColors.contains(ColorTable[ColorIdx].data()))
|
||||||
|
sprintf(Modifier, "material");
|
||||||
|
else
|
||||||
|
sprintf(Modifier, "texture");
|
||||||
if (!ModelPart.Mesh)
|
if (!ModelPart.Mesh)
|
||||||
{
|
{
|
||||||
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[ModelPart.Info];
|
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[ModelPart.Info];
|
||||||
|
|
||||||
if (Entry.second & LGEO_PIECE_SLOPE)
|
if (Entry.second & LGEO_PIECE_SLOPE)
|
||||||
{
|
{
|
||||||
sprintf(Line, "merge {\n object {\n %s%s\n texture { %s }\n }\n"
|
sprintf(Line,
|
||||||
" object {\n %s_slope\n texture { %s normal { bumps 0.3 scale 0.02 } }\n }\n"
|
" merge {\n object {\n %s%s\n %s { %s }\n }\n"
|
||||||
" matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n",
|
" object {\n %s_slope\n texture {\n %s normal { bumps 0.3 scale 0.02 }\n }\n }\n"
|
||||||
Entry.first, Suffix, ColorTable[Color].data(), Entry.first, ColorTable[Color].data(),
|
" matrix <%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g>\n }\n",
|
||||||
|
Entry.first, Suffix, Modifier, ColorTable[ColorIdx].data(), Entry.first, ColorTable[ColorIdx].data(),
|
||||||
-f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f);
|
-f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2104,8 +2495,8 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
if (!ModelPart.Info || !ModelPart.Info->GetMesh())
|
if (!ModelPart.Info || !ModelPart.Info->GetMesh())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sprintf(Line, "object {\n %s%s\n texture { %s }\n matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n",
|
sprintf(Line, " object {\n %s%s\n %s { %s }\n matrix <%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g>\n }\n",
|
||||||
Entry.first, Suffix, ColorTable[Color].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f);
|
Entry.first, Suffix, Modifier, ColorTable[ColorIdx].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2114,13 +2505,29 @@ bool Project::ExportPOVRay(const QString& FileName)
|
||||||
char Name[LC_PIECE_NAME_LEN];
|
char Name[LC_PIECE_NAME_LEN];
|
||||||
GetMeshName(ModelPart, Name);
|
GetMeshName(ModelPart, Name);
|
||||||
|
|
||||||
sprintf(Line, "object {\n lc_%s%s\n texture { %s }\n matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n",
|
sprintf(Line, " object {\n lc_%s%s\n %s { %s }\n matrix <%g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g>\n }\n",
|
||||||
Name, Suffix, ColorTable[Color].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f);
|
Name, Suffix, Modifier, ColorTable[ColorIdx].data(), -f[5], -f[4], -f[6], -f[1], -f[0], -f[2], f[9], f[8], f[10], f[13] / 25.0f, f[12] / 25.0f, f[14] / 25.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
POVFile.WriteLine(Line);
|
POVFile.WriteLine(Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sprintf(Line, "\n #if (ModelReflection = 0)\n no_reflection\n #end\n #if (ModelShadow = 0)\n no_shadow\n #end\n}\n\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
sprintf(Line, "object {\n %s\n %s { %s }\n}\n\n",
|
||||||
|
TopModelName.toLatin1().constData(), (UseLGEO ? "material" : "texture"), ColorTable[lcGetColorIndex(TopModelColorCode)].data());
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
sprintf(Line, "#if (Floor)\n object {\n plane { FloorAxis, FloorLocation hollow }\n texture {\n pigment { color srgb FloorColor }\n finish { emission 0 ambient FloorAmbient diffuse FloorDiffuse }\n }\n }\n#end\n");
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
|
||||||
|
if (!POVRayOptions.FooterIncludeFile.isEmpty())
|
||||||
|
{
|
||||||
|
sprintf(Line, "\n#include \"%s\"\n", POVRayOptions.FooterIncludeFile.toLatin1().constData());
|
||||||
|
POVFile.WriteLine(Line);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2239,7 +2646,7 @@ void Project::SaveImage()
|
||||||
|
|
||||||
if (Dialog.exec() != QDialog::Accepted)
|
if (Dialog.exec() != QDialog::Accepted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString Extension = QFileInfo(Dialog.mFileName).suffix();
|
QString Extension = QFileInfo(Dialog.mFileName).suffix();
|
||||||
|
|
||||||
if (!Extension.isEmpty())
|
if (!Extension.isEmpty())
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
|
<file>resources/action_arealight_16.png</file>
|
||||||
<file>resources/action_delete_16.png</file>
|
<file>resources/action_delete_16.png</file>
|
||||||
<file>resources/action_insert_16.png</file>
|
<file>resources/action_insert_16.png</file>
|
||||||
<file>resources/action_light_16.png</file>
|
<file>resources/action_light_16.png</file>
|
||||||
|
@ -9,6 +10,7 @@
|
||||||
<file>resources/action_rotate_16.png</file>
|
<file>resources/action_rotate_16.png</file>
|
||||||
<file>resources/action_select_16.png</file>
|
<file>resources/action_select_16.png</file>
|
||||||
<file>resources/action_spotlight_16.png</file>
|
<file>resources/action_spotlight_16.png</file>
|
||||||
|
<file>resources/action_sunlight_16.png</file>
|
||||||
<file>resources/action_zoom_16.png</file>
|
<file>resources/action_zoom_16.png</file>
|
||||||
<file>resources/edit_copy_16.png</file>
|
<file>resources/edit_copy_16.png</file>
|
||||||
<file>resources/edit_cut_16.png</file>
|
<file>resources/edit_cut_16.png</file>
|
||||||
|
@ -23,6 +25,7 @@
|
||||||
<file>resources/file_render_open_in_blender_16.png</file>
|
<file>resources/file_render_open_in_blender_16.png</file>
|
||||||
<file>resources/file_render_povray_16.png</file>
|
<file>resources/file_render_povray_16.png</file>
|
||||||
<file>resources/file_save_16.png</file>
|
<file>resources/file_save_16.png</file>
|
||||||
|
<file>resources/action_arealight.png</file>
|
||||||
<file>resources/action_camera.png</file>
|
<file>resources/action_camera.png</file>
|
||||||
<file>resources/action_color_picker.png</file>
|
<file>resources/action_color_picker.png</file>
|
||||||
<file>resources/action_color_picker_16.png</file>
|
<file>resources/action_color_picker_16.png</file>
|
||||||
|
@ -41,9 +44,11 @@
|
||||||
<file>resources/action_rotate_view.png</file>
|
<file>resources/action_rotate_view.png</file>
|
||||||
<file>resources/action_select.png</file>
|
<file>resources/action_select.png</file>
|
||||||
<file>resources/action_spotlight.png</file>
|
<file>resources/action_spotlight.png</file>
|
||||||
|
<file>resources/action_sunlight.png</file>
|
||||||
<file>resources/action_zoom.png</file>
|
<file>resources/action_zoom.png</file>
|
||||||
<file>resources/action_zoom_extents.png</file>
|
<file>resources/action_zoom_extents.png</file>
|
||||||
<file>resources/action_zoom_region.png</file>
|
<file>resources/action_zoom_region.png</file>
|
||||||
|
<file>resources/cursor_arealight.png</file>
|
||||||
<file>resources/cursor_camera.png</file>
|
<file>resources/cursor_camera.png</file>
|
||||||
<file>resources/cursor_color_picker.png</file>
|
<file>resources/cursor_color_picker.png</file>
|
||||||
<file>resources/cursor_delete.png</file>
|
<file>resources/cursor_delete.png</file>
|
||||||
|
@ -61,6 +66,7 @@
|
||||||
<file>resources/cursor_select_add.png</file>
|
<file>resources/cursor_select_add.png</file>
|
||||||
<file>resources/cursor_select_remove.png</file>
|
<file>resources/cursor_select_remove.png</file>
|
||||||
<file>resources/cursor_spotlight.png</file>
|
<file>resources/cursor_spotlight.png</file>
|
||||||
|
<file>resources/cursor_sunlight.png</file>
|
||||||
<file>resources/cursor_zoom.png</file>
|
<file>resources/cursor_zoom.png</file>
|
||||||
<file>resources/cursor_zoom_region.png</file>
|
<file>resources/cursor_zoom_region.png</file>
|
||||||
<file>resources/edit_copy.png</file>
|
<file>resources/edit_copy.png</file>
|
||||||
|
|
|
@ -160,7 +160,7 @@ void lcQPropertiesTreeDelegate::paint(QPainter *painter, const QStyleOptionViewI
|
||||||
QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
|
QColor color = static_cast<QRgb>(QApplication::style()->styleHint(QStyle::SH_Table_GridLineColor, &opt));
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setPen(QPen(color));
|
painter->setPen(QPen(color));
|
||||||
|
|
||||||
if (!m_treeWidget || (!m_treeWidget->lastColumn(index.column()) && hasValue))
|
if (!m_treeWidget || (!m_treeWidget->lastColumn(index.column()) && hasValue))
|
||||||
{
|
{
|
||||||
int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left();
|
int right = (option.direction == Qt::LeftToRight) ? option.rect.right() : option.rect.left();
|
||||||
|
@ -222,9 +222,9 @@ lcQPropertiesTree::lcQPropertiesTree(QWidget *parent) :
|
||||||
m_checkedIcon = drawCheckBox(true);
|
m_checkedIcon = drawCheckBox(true);
|
||||||
m_uncheckedIcon = drawCheckBox(false);
|
m_uncheckedIcon = drawCheckBox(false);
|
||||||
|
|
||||||
m_delegate = new lcQPropertiesTreeDelegate(parent);
|
mDelegate = new lcQPropertiesTreeDelegate(parent);
|
||||||
m_delegate->setTreeWidget(this);
|
mDelegate->setTreeWidget(this);
|
||||||
setItemDelegate(m_delegate);
|
setItemDelegate(mDelegate);
|
||||||
|
|
||||||
SetEmpty();
|
SetEmpty();
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ void lcQPropertiesTree::keyPressEvent(QKeyEvent *event)
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
case Qt::Key_Enter:
|
case Qt::Key_Enter:
|
||||||
case Qt::Key_Space: // Trigger Edit
|
case Qt::Key_Space: // Trigger Edit
|
||||||
if (!m_delegate->editedItem())
|
if (!mDelegate->editedItem())
|
||||||
{
|
{
|
||||||
if (const QTreeWidgetItem *item = currentItem())
|
if (const QTreeWidgetItem *item = currentItem())
|
||||||
{
|
{
|
||||||
|
@ -299,8 +299,8 @@ void lcQPropertiesTree::mousePressEvent(QMouseEvent *event)
|
||||||
|
|
||||||
if (item)
|
if (item)
|
||||||
{
|
{
|
||||||
if ((item != m_delegate->editedItem()) && (event->button() == Qt::LeftButton) && (header()->logicalIndexAt(event->pos().x()) == 1) &&
|
if ((item != mDelegate->editedItem()) && (event->button() == Qt::LeftButton) && (header()->logicalIndexAt(event->pos().x()) == 1) &&
|
||||||
((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled)))
|
((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled)))
|
||||||
editItem(item, 1);
|
editItem(item, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,59 +423,63 @@ protected:
|
||||||
bool mAllowEmpty;
|
bool mAllowEmpty;
|
||||||
};
|
};
|
||||||
|
|
||||||
QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item) const
|
QWidget* lcQPropertiesTree::createEditor(QWidget* Parent, QTreeWidgetItem* Item) const
|
||||||
{
|
{
|
||||||
PropertyType propertyType = (PropertyType)item->data(0, lcQPropertiesTree::PropertyTypeRole).toInt();
|
lcQPropertiesTree::PropertyType PropertyType = (lcQPropertiesTree::PropertyType)Item->data(0, lcQPropertiesTree::PropertyTypeRole).toInt();
|
||||||
|
|
||||||
switch (propertyType)
|
switch (PropertyType)
|
||||||
{
|
{
|
||||||
case PropertyGroup:
|
case PropertyGroup:
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
case PropertyBool:
|
case PropertyBool:
|
||||||
{
|
return nullptr;
|
||||||
QCheckBox *editor = new QCheckBox(parent);
|
|
||||||
bool value = item->data(0, PropertyValueRole).toBool();
|
|
||||||
|
|
||||||
editor->setChecked(value);
|
|
||||||
|
|
||||||
connect(editor, SIGNAL(toggled(bool)), this, SLOT(slotToggled(bool)));
|
|
||||||
|
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
|
|
||||||
case PropertyFloat:
|
case PropertyFloat:
|
||||||
{
|
{
|
||||||
QLineEdit *editor = new QLineEdit(parent);
|
QLineEdit* Editor = new QLineEdit(Parent);
|
||||||
float value = item->data(0, PropertyValueRole).toFloat();
|
float Value = Item->data(0, PropertyValueRole).toFloat();
|
||||||
|
QPointF Range = Item->data(0, PropertyRangeRole).toPointF();
|
||||||
|
|
||||||
editor->setValidator(new QDoubleValidator(editor));
|
Editor->setValidator(Range.isNull() ? new QDoubleValidator(Editor) : new QDoubleValidator(Range.x(), Range.y(), 1, Editor));
|
||||||
editor->setText(lcFormatValueLocalized(value));
|
Editor->setText(lcFormatValueLocalized(Value));
|
||||||
|
|
||||||
connect(editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
|
connect(Editor, &QLineEdit::returnPressed, this, &lcQPropertiesTree::slotReturnPressed);
|
||||||
|
|
||||||
return editor;
|
return Editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PropertyInteger:
|
||||||
|
{
|
||||||
|
QLineEdit* Editor = new QLineEdit(Parent);
|
||||||
|
int Value = Item->data(0, PropertyValueRole).toInt();
|
||||||
|
QPoint Range = Item->data(0, PropertyRangeRole).toPoint();
|
||||||
|
|
||||||
|
Editor->setValidator(Range.isNull() ? new QIntValidator(Editor) : new QIntValidator(Range.x(), Range.y(), Editor));
|
||||||
|
Editor->setText(QString::number(Value));
|
||||||
|
|
||||||
|
connect(Editor, &QLineEdit::returnPressed, this, &lcQPropertiesTree::slotReturnPressed);
|
||||||
|
|
||||||
|
return Editor;
|
||||||
|
}
|
||||||
|
|
||||||
case PropertyStep:
|
case PropertyStep:
|
||||||
{
|
{
|
||||||
QLineEdit* Editor = new QLineEdit(parent);
|
QLineEdit* Editor = new QLineEdit(Parent);
|
||||||
|
|
||||||
lcStep Value = item->data(0, PropertyValueRole).toUInt();
|
lcStep Value = Item->data(0, PropertyValueRole).toUInt();
|
||||||
lcStep Show = partShow->data(0, PropertyValueRole).toUInt();
|
lcStep Show = partShow->data(0, PropertyValueRole).toUInt();
|
||||||
lcStep Hide = partHide->data(0, PropertyValueRole).toUInt();
|
lcStep Hide = partHide->data(0, PropertyValueRole).toUInt();
|
||||||
|
|
||||||
if (Show && Hide)
|
if (Show && Hide)
|
||||||
{
|
{
|
||||||
if (item == partShow)
|
if (Item == partShow)
|
||||||
Editor->setValidator(new lcStepValidator(1, Hide - 1, false));
|
Editor->setValidator(new lcStepValidator(1, Hide - 1, false));
|
||||||
else
|
else
|
||||||
Editor->setValidator(new lcStepValidator(Show + 1, LC_STEP_MAX, true));
|
Editor->setValidator(new lcStepValidator(Show + 1, LC_STEP_MAX, true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Editor->setValidator(new lcStepValidator(1, LC_STEP_MAX, item == partHide));
|
Editor->setValidator(new lcStepValidator(1, LC_STEP_MAX, Item == partHide));
|
||||||
|
|
||||||
if (item != partHide || Value != LC_STEP_MAX)
|
if (Item != partHide || Value != LC_STEP_MAX)
|
||||||
Editor->setText(QString::number(Value));
|
Editor->setText(QString::number(Value));
|
||||||
|
|
||||||
connect(Editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
|
connect(Editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
|
||||||
|
@ -485,8 +489,8 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
||||||
|
|
||||||
case PropertyString:
|
case PropertyString:
|
||||||
{
|
{
|
||||||
QLineEdit *editor = new QLineEdit(parent);
|
QLineEdit *editor = new QLineEdit(Parent);
|
||||||
QString value = item->data(0, PropertyValueRole).toString();
|
QString value = Item->data(0, PropertyValueRole).toString();
|
||||||
|
|
||||||
editor->setText(value);
|
editor->setText(value);
|
||||||
|
|
||||||
|
@ -495,10 +499,49 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PropertyStringList:
|
||||||
|
{
|
||||||
|
QComboBox* editor = new QComboBox(Parent);
|
||||||
|
|
||||||
|
if (Item == mCameraProjectionItem)
|
||||||
|
{
|
||||||
|
editor->addItems( { tr("Perspective"), tr("Orthographic") } );
|
||||||
|
}
|
||||||
|
else if (Item == mLightTypeItem)
|
||||||
|
{
|
||||||
|
for (int LightTypeIndex = 0; LightTypeIndex < static_cast<int>(lcLightType::Count); LightTypeIndex++)
|
||||||
|
editor->addItem(lcLight::GetLightTypeString(static_cast<lcLightType>(LightTypeIndex)));
|
||||||
|
}
|
||||||
|
else if (Item == mLightAreaShapeItem)
|
||||||
|
{
|
||||||
|
for (int LightAreaShapeIndex = 0; LightAreaShapeIndex < static_cast<int>(lcLightAreaShape::Count); LightAreaShapeIndex++)
|
||||||
|
editor->addItem(lcLight::GetAreaShapeString(static_cast<lcLightAreaShape>(LightAreaShapeIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = Item->data(0, PropertyValueRole).toInt();
|
||||||
|
editor->setCurrentIndex(value);
|
||||||
|
|
||||||
|
connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int)));
|
||||||
|
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
case PropertyColor:
|
case PropertyColor:
|
||||||
{
|
{
|
||||||
QPushButton *editor = new QPushButton(parent);
|
QPushButton *Editor = new QPushButton(Parent);
|
||||||
int value = item->data(0, PropertyValueRole).toInt();
|
QColor Value = Item->data(0, PropertyValueRole).value<QColor>();
|
||||||
|
|
||||||
|
UpdateLightColorEditor(Editor, Value);
|
||||||
|
|
||||||
|
connect(Editor, &QPushButton::clicked, this, &lcQPropertiesTree::LightColorButtonClicked);
|
||||||
|
|
||||||
|
return Editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PropertyPieceColor:
|
||||||
|
{
|
||||||
|
QPushButton *editor = new QPushButton(Parent);
|
||||||
|
int value = Item->data(0, PropertyValueRole).toInt();
|
||||||
|
|
||||||
updateColorEditor(editor, value);
|
updateColorEditor(editor, value);
|
||||||
|
|
||||||
|
@ -509,7 +552,7 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
||||||
|
|
||||||
case PropertyPart:
|
case PropertyPart:
|
||||||
{
|
{
|
||||||
QComboBox *editor = new QComboBox(parent);
|
QComboBox *editor = new QComboBox(Parent);
|
||||||
|
|
||||||
editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||||
editor->setMinimumContentsLength(1);
|
editor->setMinimumContentsLength(1);
|
||||||
|
@ -537,7 +580,7 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
||||||
for (PieceInfo* Info : SortedPieces)
|
for (PieceInfo* Info : SortedPieces)
|
||||||
editor->addItem(Info->m_strDescription, QVariant::fromValue((void*)Info));
|
editor->addItem(Info->m_strDescription, QVariant::fromValue((void*)Info));
|
||||||
|
|
||||||
PieceInfo *info = (PieceInfo*)item->data(0, PropertyValueRole).value<void*>();
|
PieceInfo *info = (PieceInfo*)Item->data(0, PropertyValueRole).value<void*>();
|
||||||
editor->setCurrentIndex(editor->findData(QVariant::fromValue((void*)info)));
|
editor->setCurrentIndex(editor->findData(QVariant::fromValue((void*)info)));
|
||||||
|
|
||||||
connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int)));
|
connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetValue(int)));
|
||||||
|
@ -567,22 +610,38 @@ void lcQPropertiesTree::updateColorEditor(QPushButton *editor, int value) const
|
||||||
editor->setText(color->Name);
|
editor->setText(color->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcQPropertiesTree::UpdateLightColorEditor(QPushButton* Editor, QColor Color) const
|
||||||
|
{
|
||||||
|
QImage Image(12, 12, QImage::Format_ARGB32);
|
||||||
|
Image.fill(0);
|
||||||
|
|
||||||
|
QPainter Painter(&Image);
|
||||||
|
Painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
Painter.setPen(Qt::darkGray);
|
||||||
|
Painter.setBrush(Color);
|
||||||
|
Painter.drawRect(0, 0, Image.width() - 1, Image.height() - 1);
|
||||||
|
Painter.end();
|
||||||
|
|
||||||
|
Editor->setStyleSheet("Text-align:left");
|
||||||
|
Editor->setIcon(QPixmap::fromImage(Image));
|
||||||
|
Editor->setText(Color.name().toUpper());
|
||||||
|
}
|
||||||
|
|
||||||
void lcQPropertiesTree::slotToggled(bool Value)
|
void lcQPropertiesTree::slotToggled(bool Value)
|
||||||
{
|
{
|
||||||
QTreeWidgetItem* Item = m_delegate->editedItem();
|
QTreeWidgetItem* Item = mDelegate->editedItem();
|
||||||
lcModel* Model = gMainWindow->GetActiveModel();
|
lcModel* Model = gMainWindow->GetActiveModel();
|
||||||
|
lcObject* Focus = Model->GetFocusObject();
|
||||||
|
|
||||||
if (mWidgetMode == LC_PROPERTY_WIDGET_CAMERA)
|
if (mWidgetMode == LC_PROPERTY_WIDGET_LIGHT)
|
||||||
{
|
{
|
||||||
lcObject* Focus = Model->GetFocusObject();
|
lcLight* Light = (Focus && Focus->IsLight()) ? (lcLight*)Focus : nullptr;
|
||||||
|
|
||||||
if (Focus && Focus->IsCamera())
|
if (Light)
|
||||||
{
|
{
|
||||||
lcCamera* Camera = (lcCamera*)Focus;
|
if (Item == mLightCastShadowItem)
|
||||||
|
|
||||||
if (Item == cameraOrtho)
|
|
||||||
{
|
{
|
||||||
Model->SetCameraOrthographic(Camera, Value);
|
Model->SetLightCastShadow(Light, Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -591,53 +650,57 @@ void lcQPropertiesTree::slotToggled(bool Value)
|
||||||
void lcQPropertiesTree::slotReturnPressed()
|
void lcQPropertiesTree::slotReturnPressed()
|
||||||
{
|
{
|
||||||
QLineEdit* Editor = (QLineEdit*)sender();
|
QLineEdit* Editor = (QLineEdit*)sender();
|
||||||
QTreeWidgetItem* Item = m_delegate->editedItem();
|
QTreeWidgetItem* Item = mDelegate->editedItem();
|
||||||
lcModel* Model = gMainWindow->GetActiveModel();
|
lcModel* Model = gMainWindow->GetActiveModel();
|
||||||
|
|
||||||
|
lcPiece* Piece = (mFocus && mFocus->IsPiece()) ? (lcPiece*)mFocus : nullptr;
|
||||||
|
lcLight* Light = (mFocus && mFocus->IsLight()) ? (lcLight*)mFocus : nullptr;
|
||||||
|
|
||||||
|
if (Item == mPositionXItem || Item == mPositionYItem || Item == mPositionZItem)
|
||||||
|
{
|
||||||
|
lcVector3 Center;
|
||||||
|
lcMatrix33 RelativeRotation;
|
||||||
|
Model->GetMoveRotateTransform(Center, RelativeRotation);
|
||||||
|
lcVector3 Position = Center;
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
if (Item == mPositionXItem)
|
||||||
|
Position[0] = Value;
|
||||||
|
else if (Item == mPositionYItem)
|
||||||
|
Position[1] = Value;
|
||||||
|
else if (Item == mPositionZItem)
|
||||||
|
Position[2] = Value;
|
||||||
|
|
||||||
|
lcVector3 Distance = Position - Center;
|
||||||
|
|
||||||
|
Model->MoveSelectedObjects(Distance, Distance, false, true, true, true);
|
||||||
|
}
|
||||||
|
else if (Item == mRotationXItem || Item == mRotationYItem || Item == mRotationZItem)
|
||||||
|
{
|
||||||
|
lcVector3 InitialRotation(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
if (Piece)
|
||||||
|
InitialRotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
||||||
|
else if (Light)
|
||||||
|
InitialRotation = lcMatrix44ToEulerAngles(Light->mWorldMatrix) * LC_RTOD;
|
||||||
|
|
||||||
|
lcVector3 Rotation = InitialRotation;
|
||||||
|
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
if (Item == mRotationXItem)
|
||||||
|
Rotation[0] = Value;
|
||||||
|
else if (Item == mRotationYItem)
|
||||||
|
Rotation[1] = Value;
|
||||||
|
else if (Item == mRotationZItem)
|
||||||
|
Rotation[2] = Value;
|
||||||
|
|
||||||
|
Model->RotateSelectedObjects(Rotation - InitialRotation, true, false, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE)
|
if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE)
|
||||||
{
|
{
|
||||||
lcPiece* Piece = (mFocus && mFocus->IsPiece()) ? (lcPiece*)mFocus : nullptr;
|
if (Item == partShow)
|
||||||
|
|
||||||
if (Item == partPositionX || Item == partPositionY || Item == partPositionZ)
|
|
||||||
{
|
|
||||||
lcVector3 Center;
|
|
||||||
lcMatrix33 RelativeRotation;
|
|
||||||
Model->GetMoveRotateTransform(Center, RelativeRotation);
|
|
||||||
lcVector3 Position = Center;
|
|
||||||
float Value = lcParseValueLocalized(Editor->text());
|
|
||||||
|
|
||||||
if (Item == partPositionX)
|
|
||||||
Position[0] = Value;
|
|
||||||
else if (Item == partPositionY)
|
|
||||||
Position[1] = Value;
|
|
||||||
else if (Item == partPositionZ)
|
|
||||||
Position[2] = Value;
|
|
||||||
|
|
||||||
lcVector3 Distance = Position - Center;
|
|
||||||
|
|
||||||
Model->MoveSelectedObjects(Distance, Distance, false, false, true, true);
|
|
||||||
}
|
|
||||||
else if (Item == partRotationX || Item == partRotationY || Item == partRotationZ)
|
|
||||||
{
|
|
||||||
lcVector3 InitialRotation;
|
|
||||||
if (Piece)
|
|
||||||
InitialRotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
|
||||||
else
|
|
||||||
InitialRotation = lcVector3(0.0f, 0.0f, 0.0f);
|
|
||||||
lcVector3 Rotation = InitialRotation;
|
|
||||||
|
|
||||||
float Value = lcParseValueLocalized(Editor->text());
|
|
||||||
|
|
||||||
if (Item == partRotationX)
|
|
||||||
Rotation[0] = Value;
|
|
||||||
else if (Item == partRotationY)
|
|
||||||
Rotation[1] = Value;
|
|
||||||
else if (Item == partRotationZ)
|
|
||||||
Rotation[2] = Value;
|
|
||||||
|
|
||||||
Model->RotateSelectedPieces(Rotation - InitialRotation, true, false, true, true);
|
|
||||||
}
|
|
||||||
else if (Item == partShow)
|
|
||||||
{
|
{
|
||||||
bool Ok = false;
|
bool Ok = false;
|
||||||
lcStep Step = Editor->text().toUInt(&Ok);
|
lcStep Step = Editor->text().toUInt(&Ok);
|
||||||
|
@ -736,7 +799,7 @@ void lcQPropertiesTree::slotReturnPressed()
|
||||||
|
|
||||||
Model->SetCameraZFar(Camera, Value);
|
Model->SetCameraZFar(Camera, Value);
|
||||||
}
|
}
|
||||||
else if (Item == cameraName)
|
else if (Item == mCameraNameItem)
|
||||||
{
|
{
|
||||||
QString Value = Editor->text();
|
QString Value = Editor->text();
|
||||||
|
|
||||||
|
@ -744,23 +807,99 @@ void lcQPropertiesTree::slotReturnPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mWidgetMode == LC_PROPERTY_WIDGET_LIGHT)
|
||||||
|
{
|
||||||
|
if (Light)
|
||||||
|
{
|
||||||
|
if (Item == mLightAttenuationDistanceItem)
|
||||||
|
{
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetLightAttenuationDistance(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightAttenuationPowerItem)
|
||||||
|
{
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetLightAttenuationPower(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightSpotConeAngleItem)
|
||||||
|
{
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetSpotLightConeAngle(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightSpotPenumbraAngleItem)
|
||||||
|
{
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetSpotLightPenumbraAngle(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightSpotTightnessItem)
|
||||||
|
{
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetSpotLightTightness(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightAreaGridXItem)
|
||||||
|
{
|
||||||
|
lcVector2i AreaGrid = Light->GetAreaGrid();
|
||||||
|
AreaGrid.x = Editor->text().toInt();
|
||||||
|
|
||||||
|
Model->SetLightAreaGrid(Light, AreaGrid);
|
||||||
|
}
|
||||||
|
else if (Item == mLightAreaGridYItem)
|
||||||
|
{
|
||||||
|
lcVector2i AreaGrid = Light->GetAreaGrid();
|
||||||
|
AreaGrid.y = Editor->text().toInt();
|
||||||
|
|
||||||
|
Model->SetLightAreaGrid(Light, AreaGrid);
|
||||||
|
}
|
||||||
|
else if (Item == mLightSizeXItem)
|
||||||
|
{
|
||||||
|
lcVector2 Value = Light->GetSize();
|
||||||
|
Value[0] = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetLightSize(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightSizeYItem)
|
||||||
|
{
|
||||||
|
lcVector2 Value = Light->GetSize();
|
||||||
|
Value[1] = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetLightSize(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightPowerItem)
|
||||||
|
{
|
||||||
|
float Value = lcParseValueLocalized(Editor->text());
|
||||||
|
|
||||||
|
Model->SetLightPower(Light, Value);
|
||||||
|
}
|
||||||
|
else if (Item == mLightNameItem)
|
||||||
|
{
|
||||||
|
QString Value = Editor->text();
|
||||||
|
|
||||||
|
Model->SetLightName(Light, Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcQPropertiesTree::slotSetValue(int Value)
|
void lcQPropertiesTree::slotSetValue(int Value)
|
||||||
{
|
{
|
||||||
QTreeWidgetItem* Item = m_delegate->editedItem();
|
QTreeWidgetItem* Item = mDelegate->editedItem();
|
||||||
lcModel* Model = gMainWindow->GetActiveModel();
|
lcModel* Model = gMainWindow->GetActiveModel();
|
||||||
|
|
||||||
if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE)
|
if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE)
|
||||||
{
|
{
|
||||||
if (Item == partColor)
|
if (Item == mPieceColorItem)
|
||||||
{
|
{
|
||||||
Model->SetSelectedPiecesColorIndex(Value);
|
Model->SetSelectedPiecesColorIndex(Value);
|
||||||
|
|
||||||
QPushButton *editor = (QPushButton*)m_delegate->editor();
|
QPushButton *editor = (QPushButton*)mDelegate->editor();
|
||||||
updateColorEditor(editor, Value);
|
updateColorEditor(editor, Value);
|
||||||
}
|
}
|
||||||
else if (Item == partID)
|
else if (Item == mPieceIdItem)
|
||||||
{
|
{
|
||||||
QComboBox *editor = (QComboBox*)sender();
|
QComboBox *editor = (QComboBox*)sender();
|
||||||
|
|
||||||
|
@ -775,6 +914,37 @@ void lcQPropertiesTree::slotSetValue(int Value)
|
||||||
gMainWindow->PreviewPiece(Info->mFileName, ColorCode, false);
|
gMainWindow->PreviewPiece(Info->mFileName, ColorCode, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mWidgetMode == LC_PROPERTY_WIDGET_CAMERA)
|
||||||
|
{
|
||||||
|
lcObject* Focus = Model->GetFocusObject();
|
||||||
|
|
||||||
|
if (Focus && Focus->IsCamera())
|
||||||
|
{
|
||||||
|
lcCamera* Camera = (lcCamera*)Focus;
|
||||||
|
|
||||||
|
if (Item == mCameraProjectionItem)
|
||||||
|
{
|
||||||
|
Model->SetCameraOrthographic(Camera, Value == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mWidgetMode == LC_PROPERTY_WIDGET_LIGHT)
|
||||||
|
{
|
||||||
|
lcObject* Focus = Model->GetFocusObject();
|
||||||
|
lcLight* Light = (Focus && Focus->IsLight()) ? (lcLight*)Focus : nullptr;
|
||||||
|
|
||||||
|
if (Light)
|
||||||
|
{
|
||||||
|
if (Item == mLightTypeItem)
|
||||||
|
{
|
||||||
|
Model->SetLightType(Light, static_cast<lcLightType>(Value));
|
||||||
|
}
|
||||||
|
else if (Item == mLightAreaShapeItem)
|
||||||
|
{
|
||||||
|
Model->SetLightAreaShape(Light, static_cast<lcLightAreaShape>(Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcQPropertiesTree::slotColorButtonClicked()
|
void lcQPropertiesTree::slotColorButtonClicked()
|
||||||
|
@ -822,6 +992,28 @@ void lcQPropertiesTree::slotColorButtonClicked()
|
||||||
Popup->show();
|
Popup->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lcQPropertiesTree::LightColorButtonClicked()
|
||||||
|
{
|
||||||
|
lcModel* Model = gMainWindow->GetActiveModel();
|
||||||
|
lcObject* Focus = Model->GetFocusObject();
|
||||||
|
lcLight* Light = (Focus && Focus->IsLight()) ? (lcLight*)Focus : nullptr;
|
||||||
|
|
||||||
|
if (!Light)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QColor Color = QColorDialog::getColor(lcQColorFromVector3(Light->GetColor()), this, tr("Select Light Color"));
|
||||||
|
|
||||||
|
if (!Color.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Model->SetLightColor(Light, lcVector3FromQColor(Color));
|
||||||
|
|
||||||
|
QPushButton* Editor = qobject_cast<QPushButton*>(mDelegate->editor());
|
||||||
|
|
||||||
|
if (Editor)
|
||||||
|
UpdateLightColorEditor(Editor, Color);
|
||||||
|
}
|
||||||
|
|
||||||
QTreeWidgetItem *lcQPropertiesTree::addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType)
|
QTreeWidgetItem *lcQPropertiesTree::addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType)
|
||||||
{
|
{
|
||||||
QTreeWidgetItem *newItem;
|
QTreeWidgetItem *newItem;
|
||||||
|
@ -848,20 +1040,13 @@ void lcQPropertiesTree::SetEmpty()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
partPosition = nullptr;
|
mPieceAttributesItem = nullptr;
|
||||||
partPositionX = nullptr;
|
|
||||||
partPositionY = nullptr;
|
|
||||||
partPositionZ = nullptr;
|
|
||||||
partRotation = nullptr;
|
|
||||||
partRotationX = nullptr;
|
|
||||||
partRotationY = nullptr;
|
|
||||||
partRotationZ = nullptr;
|
|
||||||
partVisibility = nullptr;
|
partVisibility = nullptr;
|
||||||
partShow = nullptr;
|
partShow = nullptr;
|
||||||
partHide = nullptr;
|
partHide = nullptr;
|
||||||
partAppearance = nullptr;
|
partAppearance = nullptr;
|
||||||
partColor = nullptr;
|
mPieceColorItem = nullptr;
|
||||||
partID = nullptr;
|
mPieceIdItem = nullptr;
|
||||||
|
|
||||||
cameraPosition = nullptr;
|
cameraPosition = nullptr;
|
||||||
cameraPositionX = nullptr;
|
cameraPositionX = nullptr;
|
||||||
|
@ -875,12 +1060,38 @@ void lcQPropertiesTree::SetEmpty()
|
||||||
cameraUpX = nullptr;
|
cameraUpX = nullptr;
|
||||||
cameraUpY = nullptr;
|
cameraUpY = nullptr;
|
||||||
cameraUpZ = nullptr;
|
cameraUpZ = nullptr;
|
||||||
cameraSettings = nullptr;
|
mCameraAttributesItem = nullptr;
|
||||||
cameraOrtho = nullptr;
|
mCameraProjectionItem = nullptr;
|
||||||
cameraFOV = nullptr;
|
cameraFOV = nullptr;
|
||||||
cameraNear = nullptr;
|
cameraNear = nullptr;
|
||||||
cameraFar = nullptr;
|
cameraFar = nullptr;
|
||||||
cameraName = nullptr;
|
mCameraNameItem = nullptr;
|
||||||
|
|
||||||
|
mLightColorItem = nullptr;
|
||||||
|
mLightPowerItem = nullptr;
|
||||||
|
mLightAttributesItem = nullptr;
|
||||||
|
mLightTypeItem = nullptr;
|
||||||
|
mLightNameItem = nullptr;
|
||||||
|
mLightAttenuationDistanceItem = nullptr;
|
||||||
|
mLightAttenuationPowerItem = nullptr;
|
||||||
|
mLightSpotConeAngleItem = nullptr;
|
||||||
|
mLightSpotPenumbraAngleItem = nullptr;
|
||||||
|
mLightSpotTightnessItem = nullptr;
|
||||||
|
mLightAreaShapeItem = nullptr;
|
||||||
|
mLightAreaGridXItem = nullptr;
|
||||||
|
mLightAreaGridYItem = nullptr;
|
||||||
|
mLightSizeXItem = nullptr;
|
||||||
|
mLightSizeYItem = nullptr;
|
||||||
|
mLightCastShadowItem = nullptr;
|
||||||
|
|
||||||
|
mPositionItem = nullptr;
|
||||||
|
mPositionXItem = nullptr;
|
||||||
|
mPositionYItem = nullptr;
|
||||||
|
mPositionZItem = nullptr;
|
||||||
|
mRotationItem = nullptr;
|
||||||
|
mRotationXItem = nullptr;
|
||||||
|
mRotationYItem = nullptr;
|
||||||
|
mRotationZItem = nullptr;
|
||||||
|
|
||||||
mWidgetMode = LC_PROPERTY_WIDGET_EMPTY;
|
mWidgetMode = LC_PROPERTY_WIDGET_EMPTY;
|
||||||
mFocus = nullptr;
|
mFocus = nullptr;
|
||||||
|
@ -892,23 +1103,23 @@ void lcQPropertiesTree::SetPiece(const lcArray<lcObject*>& Selection, lcObject*
|
||||||
{
|
{
|
||||||
SetEmpty();
|
SetEmpty();
|
||||||
|
|
||||||
partPosition = addProperty(nullptr, tr("Position"), PropertyGroup);
|
mPieceAttributesItem = addProperty(nullptr, tr("Piece Attributes"), PropertyGroup);
|
||||||
partPositionX = addProperty(partPosition, tr("X"), PropertyFloat);
|
mPieceIdItem = addProperty(mPieceAttributesItem, tr("Part"), PropertyPart);
|
||||||
partPositionY = addProperty(partPosition, tr("Y"), PropertyFloat);
|
mPieceColorItem = addProperty(mPieceAttributesItem, tr("Color"), PropertyPieceColor);
|
||||||
partPositionZ = addProperty(partPosition, tr("Z"), PropertyFloat);
|
|
||||||
|
|
||||||
partRotation = addProperty(nullptr, tr("Rotation"), PropertyGroup);
|
|
||||||
partRotationX = addProperty(partRotation, tr("X"), PropertyFloat);
|
|
||||||
partRotationY = addProperty(partRotation, tr("Y"), PropertyFloat);
|
|
||||||
partRotationZ = addProperty(partRotation, tr("Z"), PropertyFloat);
|
|
||||||
|
|
||||||
partVisibility = addProperty(nullptr, tr("Visible Steps"), PropertyGroup);
|
partVisibility = addProperty(nullptr, tr("Visible Steps"), PropertyGroup);
|
||||||
partShow = addProperty(partVisibility, tr("Show"), PropertyStep);
|
partShow = addProperty(partVisibility, tr("Show"), PropertyStep);
|
||||||
partHide = addProperty(partVisibility, tr("Hide"), PropertyStep);
|
partHide = addProperty(partVisibility, tr("Hide"), PropertyStep);
|
||||||
|
|
||||||
partAppearance = addProperty(nullptr, tr("Appearance"), PropertyGroup);
|
mPositionItem = addProperty(nullptr, tr("Position"), PropertyGroup);
|
||||||
partColor = addProperty(partAppearance, tr("Color"), PropertyColor);
|
mPositionXItem = addProperty(mPositionItem, tr("X"), PropertyFloat);
|
||||||
partID = addProperty(partAppearance, tr("Part"), PropertyPart);
|
mPositionYItem = addProperty(mPositionItem, tr("Y"), PropertyFloat);
|
||||||
|
mPositionZItem = addProperty(mPositionItem, tr("Z"), PropertyFloat);
|
||||||
|
|
||||||
|
mRotationItem = addProperty(nullptr, tr("Rotation"), PropertyGroup);
|
||||||
|
mRotationXItem = addProperty(mRotationItem, tr("X"), PropertyFloat);
|
||||||
|
mRotationYItem = addProperty(mRotationItem, tr("Y"), PropertyFloat);
|
||||||
|
mRotationZItem = addProperty(mRotationItem, tr("Z"), PropertyFloat);
|
||||||
|
|
||||||
mWidgetMode = LC_PROPERTY_WIDGET_PIECE;
|
mWidgetMode = LC_PROPERTY_WIDGET_PIECE;
|
||||||
}
|
}
|
||||||
|
@ -919,25 +1130,29 @@ void lcQPropertiesTree::SetPiece(const lcArray<lcObject*>& Selection, lcObject*
|
||||||
|
|
||||||
lcVector3 Position;
|
lcVector3 Position;
|
||||||
lcMatrix33 RelativeRotation;
|
lcMatrix33 RelativeRotation;
|
||||||
|
|
||||||
Model->GetMoveRotateTransform(Position, RelativeRotation);
|
Model->GetMoveRotateTransform(Position, RelativeRotation);
|
||||||
partPositionX->setText(1, lcFormatValueLocalized(Position[0]));
|
|
||||||
partPositionX->setData(0, PropertyValueRole, Position[0]);
|
mPositionXItem->setText(1, lcFormatValueLocalized(Position[0]));
|
||||||
partPositionY->setText(1, lcFormatValueLocalized(Position[1]));
|
mPositionXItem->setData(0, PropertyValueRole, Position[0]);
|
||||||
partPositionY->setData(0, PropertyValueRole, Position[1]);
|
mPositionYItem->setText(1, lcFormatValueLocalized(Position[1]));
|
||||||
partPositionZ->setText(1, lcFormatValueLocalized(Position[2]));
|
mPositionYItem->setData(0, PropertyValueRole, Position[1]);
|
||||||
partPositionZ->setData(0, PropertyValueRole, Position[2]);
|
mPositionZItem->setText(1, lcFormatValueLocalized(Position[2]));
|
||||||
|
mPositionZItem->setData(0, PropertyValueRole, Position[2]);
|
||||||
|
|
||||||
lcVector3 Rotation;
|
lcVector3 Rotation;
|
||||||
|
|
||||||
if (Piece)
|
if (Piece)
|
||||||
Rotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
Rotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
||||||
else
|
else
|
||||||
Rotation = lcVector3(0.0f, 0.0f, 0.0f);
|
Rotation = lcVector3(0.0f, 0.0f, 0.0f);
|
||||||
partRotationX->setText(1, lcFormatValueLocalized(Rotation[0]));
|
|
||||||
partRotationX->setData(0, PropertyValueRole, Rotation[0]);
|
mRotationXItem->setText(1, lcFormatValueLocalized(Rotation[0]));
|
||||||
partRotationY->setText(1, lcFormatValueLocalized(Rotation[1]));
|
mRotationXItem->setData(0, PropertyValueRole, Rotation[0]);
|
||||||
partRotationY->setData(0, PropertyValueRole, Rotation[1]);
|
mRotationYItem->setText(1, lcFormatValueLocalized(Rotation[1]));
|
||||||
partRotationZ->setText(1, lcFormatValueLocalized(Rotation[2]));
|
mRotationYItem->setData(0, PropertyValueRole, Rotation[1]);
|
||||||
partRotationZ->setData(0, PropertyValueRole, Rotation[2]);
|
mRotationZItem->setText(1, lcFormatValueLocalized(Rotation[2]));
|
||||||
|
mRotationZItem->setData(0, PropertyValueRole, Rotation[2]);
|
||||||
|
|
||||||
lcStep Show = 0;
|
lcStep Show = 0;
|
||||||
lcStep Hide = 0;
|
lcStep Hide = 0;
|
||||||
|
@ -1008,14 +1223,14 @@ void lcQPropertiesTree::SetPiece(const lcArray<lcObject*>& Selection, lcObject*
|
||||||
painter.drawRect(0, 0, img.width() - 1, img.height() - 1);
|
painter.drawRect(0, 0, img.width() - 1, img.height() - 1);
|
||||||
painter.end();
|
painter.end();
|
||||||
|
|
||||||
partColor->setIcon(1, QIcon(QPixmap::fromImage(img)));
|
mPieceColorItem->setIcon(1, QIcon(QPixmap::fromImage(img)));
|
||||||
partColor->setText(1, color->Name);
|
mPieceColorItem->setText(1, color->Name);
|
||||||
partColor->setData(0, PropertyValueRole, ColorIndex);
|
mPieceColorItem->setData(0, PropertyValueRole, ColorIndex);
|
||||||
|
|
||||||
QString text = Info ? Info->m_strDescription : QString();
|
QString text = Info ? Info->m_strDescription : QString();
|
||||||
partID->setText(1, text);
|
mPieceIdItem->setText(1, text);
|
||||||
partID->setToolTip(1, text);
|
mPieceIdItem->setToolTip(1, text);
|
||||||
partID->setData(0, PropertyValueRole, QVariant::fromValue((void*)Info));
|
mPieceIdItem->setData(0, PropertyValueRole, QVariant::fromValue((void*)Info));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
||||||
|
@ -1024,6 +1239,13 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
||||||
{
|
{
|
||||||
SetEmpty();
|
SetEmpty();
|
||||||
|
|
||||||
|
mCameraAttributesItem = addProperty(nullptr, tr("Camera Attributes"), PropertyGroup);
|
||||||
|
mCameraNameItem = addProperty(mCameraAttributesItem, tr("Name"), PropertyString);
|
||||||
|
mCameraProjectionItem = addProperty(mCameraAttributesItem, tr("Projection"), PropertyStringList);
|
||||||
|
cameraFOV = addProperty(mCameraAttributesItem, tr("FOV"), PropertyFloat);
|
||||||
|
cameraNear = addProperty(mCameraAttributesItem, tr("Near"), PropertyFloat);
|
||||||
|
cameraFar = addProperty(mCameraAttributesItem, tr("Far"), PropertyFloat);
|
||||||
|
|
||||||
cameraPosition = addProperty(nullptr, tr("Position"), PropertyGroup);
|
cameraPosition = addProperty(nullptr, tr("Position"), PropertyGroup);
|
||||||
cameraPositionX = addProperty(cameraPosition, tr("X"), PropertyFloat);
|
cameraPositionX = addProperty(cameraPosition, tr("X"), PropertyFloat);
|
||||||
cameraPositionY = addProperty(cameraPosition, tr("Y"), PropertyFloat);
|
cameraPositionY = addProperty(cameraPosition, tr("Y"), PropertyFloat);
|
||||||
|
@ -1039,13 +1261,6 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
||||||
cameraUpY = addProperty(cameraUp, tr("Y"), PropertyFloat);
|
cameraUpY = addProperty(cameraUp, tr("Y"), PropertyFloat);
|
||||||
cameraUpZ = addProperty(cameraUp, tr("Z"), PropertyFloat);
|
cameraUpZ = addProperty(cameraUp, tr("Z"), PropertyFloat);
|
||||||
|
|
||||||
cameraSettings = addProperty(nullptr, tr("Up"), PropertyGroup);
|
|
||||||
cameraOrtho = addProperty(cameraSettings, tr("Orthographic"), PropertyBool);
|
|
||||||
cameraFOV = addProperty(cameraSettings, tr("FOV"), PropertyFloat);
|
|
||||||
cameraNear = addProperty(cameraSettings, tr("Near"), PropertyFloat);
|
|
||||||
cameraFar = addProperty(cameraSettings, tr("Far"), PropertyFloat);
|
|
||||||
cameraName = addProperty(cameraSettings, tr("Name"), PropertyString);
|
|
||||||
|
|
||||||
mWidgetMode = LC_PROPERTY_WIDGET_CAMERA;
|
mWidgetMode = LC_PROPERTY_WIDGET_CAMERA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,8 +1310,8 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
||||||
cameraUpZ->setText(1, lcFormatValueLocalized(UpVector[2]));
|
cameraUpZ->setText(1, lcFormatValueLocalized(UpVector[2]));
|
||||||
cameraUpZ->setData(0, PropertyValueRole, UpVector[2]);
|
cameraUpZ->setData(0, PropertyValueRole, UpVector[2]);
|
||||||
|
|
||||||
cameraOrtho->setText(1, Ortho ? "True" : "False");
|
mCameraProjectionItem->setText(1, Ortho ? tr("Orthographic") : tr("Perspective"));
|
||||||
cameraOrtho->setData(0, PropertyValueRole, Ortho);
|
mCameraProjectionItem->setData(0, PropertyValueRole, Ortho);
|
||||||
cameraFOV->setText(1, lcFormatValueLocalized(FoV));
|
cameraFOV->setText(1, lcFormatValueLocalized(FoV));
|
||||||
cameraFOV->setData(0, PropertyValueRole, FoV);
|
cameraFOV->setData(0, PropertyValueRole, FoV);
|
||||||
cameraNear->setText(1, lcFormatValueLocalized(ZNear));
|
cameraNear->setText(1, lcFormatValueLocalized(ZNear));
|
||||||
|
@ -1104,18 +1319,259 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
||||||
cameraFar->setText(1, lcFormatValueLocalized(ZFar));
|
cameraFar->setText(1, lcFormatValueLocalized(ZFar));
|
||||||
cameraFar->setData(0, PropertyValueRole, ZFar);
|
cameraFar->setData(0, PropertyValueRole, ZFar);
|
||||||
|
|
||||||
cameraName->setText(1, Name);
|
mCameraNameItem->setText(1, Name);
|
||||||
cameraName->setData(0, PropertyValueRole, Name);
|
mCameraNameItem->setData(0, PropertyValueRole, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcQPropertiesTree::SetLight(lcObject* Focus)
|
void lcQPropertiesTree::SetLight(lcObject* Focus)
|
||||||
{
|
{
|
||||||
Q_UNUSED(Focus);
|
lcLight* Light = (Focus && Focus->IsLight()) ? (lcLight*)Focus : nullptr;
|
||||||
|
|
||||||
SetEmpty();
|
QString Name = tr("Light");
|
||||||
mFocus = nullptr;
|
lcLightType LightType = lcLightType::Point;
|
||||||
|
lcLightAreaShape LightAreaShape = lcLightAreaShape::Rectangle;
|
||||||
|
lcVector2 LightSize(0.0f, 0.0f);
|
||||||
|
lcVector2i AreaGrid(2, 2);
|
||||||
|
float Power = 0.0f;
|
||||||
|
float AttenuationDistance = 0.0f;
|
||||||
|
float AttenuationPower = 0.0f;
|
||||||
|
bool CastShadow = true;
|
||||||
|
lcVector3 Position(0.0f, 0.0f, 0.0f);
|
||||||
|
QColor Color(Qt::white);
|
||||||
|
float SpotConeAngle = 0.0f, SpotPenumbraAngle = 0.0f, SpotTightness = 0.0f;
|
||||||
|
|
||||||
// todo: light properties
|
if (Light)
|
||||||
|
{
|
||||||
|
Name = Light->GetName();
|
||||||
|
|
||||||
|
CastShadow = Light->GetCastShadow();
|
||||||
|
Position = Light->GetPosition();
|
||||||
|
Color = lcQColorFromVector3(Light->GetColor());
|
||||||
|
Power = Light->GetPower();
|
||||||
|
AttenuationDistance = Light->GetAttenuationDistance();
|
||||||
|
AttenuationPower = Light->GetAttenuationPower();
|
||||||
|
SpotConeAngle = Light->GetSpotConeAngle();
|
||||||
|
SpotPenumbraAngle = Light->GetSpotPenumbraAngle();
|
||||||
|
SpotTightness = Light->GetSpotTightness();
|
||||||
|
|
||||||
|
LightType = Light->GetLightType();
|
||||||
|
LightAreaShape = Light->GetAreaShape();
|
||||||
|
LightSize = Light->GetSize();
|
||||||
|
AreaGrid = Light->GetAreaGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWidgetMode != LC_PROPERTY_WIDGET_LIGHT || mLightType != LightType)
|
||||||
|
{
|
||||||
|
SetEmpty();
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
mLightAttributesItem = addProperty(nullptr, tr("Light Attributes"), PropertyGroup);
|
||||||
|
mLightNameItem = addProperty(mLightAttributesItem, tr("Name"), PropertyString);
|
||||||
|
mLightTypeItem = addProperty(mLightAttributesItem, tr("Type"), PropertyStringList);
|
||||||
|
|
||||||
|
mLightColorItem = addProperty(mLightAttributesItem, tr("Color"), PropertyColor);
|
||||||
|
mLightColorItem->setToolTip(1, tr("Color of the emitted light."));
|
||||||
|
|
||||||
|
mLightPowerItem = addProperty(mLightAttributesItem, tr("Power"), PropertyFloat);
|
||||||
|
mLightPowerItem->setToolTip(1, tr("Power of the light (Watts in Blender)."));
|
||||||
|
|
||||||
|
mLightCastShadowItem = addProperty(mLightAttributesItem, tr("Cast Shadows"), PropertyBool);
|
||||||
|
|
||||||
|
mLightAttenuationDistanceItem = addProperty(mLightAttributesItem, tr("Attenuation Distance"), PropertyFloat);
|
||||||
|
mLightAttenuationDistanceItem->setToolTip(1, tr("The distance at which the full light intensity arrives (POV-Ray only)."));
|
||||||
|
|
||||||
|
mLightAttenuationPowerItem = addProperty(mLightAttributesItem, tr("Attenuation Power"), PropertyFloat);
|
||||||
|
mLightAttenuationPowerItem->setToolTip(1, tr("Light falloff rate (POV-Ray only)."));
|
||||||
|
|
||||||
|
switch (LightType)
|
||||||
|
{
|
||||||
|
case lcLightType::Point:
|
||||||
|
mLightSizeXItem = addProperty(mLightAttributesItem, tr("Radius"), PropertyFloat);
|
||||||
|
mLightSizeXItem->setToolTip(1, tr("Shadow soft size (Blender only)."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Spot:
|
||||||
|
mLightSpotConeAngleItem = addProperty(mLightAttributesItem, tr("Spot Cone Angle"), PropertyFloat);
|
||||||
|
mLightSpotConeAngleItem->setToolTip(1, tr("The angle (in degrees) of the spot light's beam."));
|
||||||
|
|
||||||
|
mLightSpotPenumbraAngleItem = addProperty(mLightAttributesItem, tr("Spot Penumbra Angle"), PropertyFloat);
|
||||||
|
mLightSpotPenumbraAngleItem->setToolTip(1, tr("The angle (in degrees) over which the intensity of the spot light falls off to zero."));
|
||||||
|
|
||||||
|
mLightSpotTightnessItem = addProperty(mLightAttributesItem, tr("Spot Tightness"), PropertyFloat);
|
||||||
|
mLightSpotTightnessItem->setToolTip(1, tr("Additional exponential spot light edge softening (POV-Ray only)."));
|
||||||
|
|
||||||
|
mLightSizeXItem = addProperty(mLightAttributesItem, tr("Radius"), PropertyFloat);
|
||||||
|
mLightSizeXItem->setToolTip(1, tr("Shadow soft size (Blender only)."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Directional:
|
||||||
|
mLightSizeXItem = addProperty(mLightAttributesItem, tr("Angle"), PropertyFloat);
|
||||||
|
mLightSizeXItem->setToolTip(1, tr("Angular diameter of the light (Blender only)."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Area:
|
||||||
|
mLightAreaShapeItem = addProperty(mLightAttributesItem, tr("Area Shape"), PropertyStringList);
|
||||||
|
mLightAreaShapeItem->setToolTip(1, tr("The shape of the area light."));
|
||||||
|
|
||||||
|
switch (LightAreaShape)
|
||||||
|
{
|
||||||
|
case lcLightAreaShape::Rectangle:
|
||||||
|
case lcLightAreaShape::Ellipse:
|
||||||
|
mLightSizeXItem = addProperty(mLightAttributesItem, tr("Area Width"), PropertyFloat);
|
||||||
|
mLightSizeXItem->setToolTip(1, tr("The width (X direction) of the area light."));
|
||||||
|
|
||||||
|
mLightSizeYItem = addProperty(mLightAttributesItem, tr("Area Height"), PropertyFloat);
|
||||||
|
mLightSizeYItem->setToolTip(1, tr("The height (Y direction) of the area light."));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightAreaShape::Square:
|
||||||
|
case lcLightAreaShape::Disk:
|
||||||
|
mLightSizeXItem = addProperty(mLightAttributesItem, tr("Area Size"), PropertyFloat);
|
||||||
|
mLightSizeXItem->setToolTip(1, tr("The size of the area light."));
|
||||||
|
|
||||||
|
mLightSizeYItem = nullptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightAreaShape::Count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLightAreaGridXItem = addProperty(mLightAttributesItem, tr("Area Grid X"), PropertyInteger);
|
||||||
|
mLightAreaGridXItem->setToolTip(1, tr("Number of point sources along the X axis (POV-Ray only)."));
|
||||||
|
mLightAreaGridXItem->setData(0, PropertyRangeRole, QPointF(1, INT_MAX));
|
||||||
|
|
||||||
|
mLightAreaGridYItem = addProperty(mLightAttributesItem, tr("Area Grid Y"), PropertyInteger);
|
||||||
|
mLightAreaGridYItem->setToolTip(1, tr("Number of point sources along the Y axis (POV-Ray only)."));
|
||||||
|
mLightAreaGridYItem->setData(0, PropertyRangeRole, QPointF(1, INT_MAX));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPositionItem = addProperty(nullptr, tr("Position"), PropertyGroup);
|
||||||
|
mPositionXItem = addProperty(mPositionItem, tr("X"), PropertyFloat);
|
||||||
|
mPositionYItem = addProperty(mPositionItem, tr("Y"), PropertyFloat);
|
||||||
|
mPositionZItem = addProperty(mPositionItem, tr("Z"), PropertyFloat);
|
||||||
|
|
||||||
|
if (LightType != lcLightType::Point)
|
||||||
|
{
|
||||||
|
mRotationItem = addProperty(nullptr, tr("Rotation"), PropertyGroup);
|
||||||
|
mRotationXItem = addProperty(mRotationItem, tr("X"), PropertyFloat);
|
||||||
|
mRotationYItem = addProperty(mRotationItem, tr("Y"), PropertyFloat);
|
||||||
|
mRotationZItem = addProperty(mRotationItem, tr("Z"), PropertyFloat);
|
||||||
|
}
|
||||||
|
|
||||||
|
mWidgetMode = LC_PROPERTY_WIDGET_LIGHT;
|
||||||
|
mLightType = LightType;
|
||||||
|
}
|
||||||
|
|
||||||
|
mFocus = Light;
|
||||||
|
|
||||||
|
mPositionXItem->setText(1, lcFormatValueLocalized(Position[0]));
|
||||||
|
mPositionXItem->setData(0, PropertyValueRole, Position[0]);
|
||||||
|
mPositionYItem->setText(1, lcFormatValueLocalized(Position[1]));
|
||||||
|
mPositionYItem->setData(0, PropertyValueRole, Position[1]);
|
||||||
|
mPositionZItem->setText(1, lcFormatValueLocalized(Position[2]));
|
||||||
|
mPositionZItem->setData(0, PropertyValueRole, Position[2]);
|
||||||
|
|
||||||
|
if (LightType != lcLightType::Point)
|
||||||
|
{
|
||||||
|
lcVector3 Rotation;
|
||||||
|
|
||||||
|
if (Light)
|
||||||
|
Rotation = lcMatrix44ToEulerAngles(Light->mWorldMatrix) * LC_RTOD;
|
||||||
|
else
|
||||||
|
Rotation = lcVector3(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
mRotationXItem->setText(1, lcFormatValueLocalized(Rotation[0]));
|
||||||
|
mRotationXItem->setData(0, PropertyValueRole, Rotation[0]);
|
||||||
|
mRotationYItem->setText(1, lcFormatValueLocalized(Rotation[1]));
|
||||||
|
mRotationYItem->setData(0, PropertyValueRole, Rotation[1]);
|
||||||
|
mRotationZItem->setText(1, lcFormatValueLocalized(Rotation[2]));
|
||||||
|
mRotationZItem->setData(0, PropertyValueRole, Rotation[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage ColorImage(16, 16, QImage::Format_ARGB32);
|
||||||
|
ColorImage.fill(0);
|
||||||
|
|
||||||
|
QPainter painter(&ColorImage);
|
||||||
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
painter.setPen(Qt::darkGray);
|
||||||
|
painter.setBrush(Color);
|
||||||
|
painter.drawRect(0, 0, ColorImage.width() - 1, ColorImage.height() - 1);
|
||||||
|
painter.end();
|
||||||
|
|
||||||
|
mLightColorItem->setIcon(1, QIcon(QPixmap::fromImage(ColorImage)));
|
||||||
|
mLightColorItem->setText(1, Color.name().toUpper());
|
||||||
|
mLightColorItem->setData(0, PropertyValueRole, Color);
|
||||||
|
|
||||||
|
mLightPowerItem->setText(1, lcFormatValueLocalized(Power));
|
||||||
|
mLightPowerItem->setData(0, PropertyValueRole, Power);
|
||||||
|
|
||||||
|
mLightAttenuationDistanceItem->setText(1, lcFormatValueLocalized(AttenuationDistance));
|
||||||
|
mLightAttenuationDistanceItem->setData(0, PropertyValueRole, AttenuationDistance);
|
||||||
|
mLightAttenuationDistanceItem->setData(0, PropertyRangeRole, QPointF(0.0, FLT_MAX));
|
||||||
|
|
||||||
|
mLightAttenuationPowerItem->setText(1, lcFormatValueLocalized(AttenuationPower));
|
||||||
|
mLightAttenuationPowerItem->setData(0, PropertyValueRole, AttenuationPower);
|
||||||
|
mLightAttenuationPowerItem->setData(0, PropertyRangeRole, QPointF(0.0, FLT_MAX));
|
||||||
|
|
||||||
|
mLightTypeItem->setText(1, lcLight::GetLightTypeString(LightType));
|
||||||
|
mLightTypeItem->setData(0, PropertyValueRole, static_cast<int>(LightType));
|
||||||
|
|
||||||
|
mLightCastShadowItem->setCheckState(1, CastShadow ? Qt::Checked : Qt::Unchecked);
|
||||||
|
mLightCastShadowItem->setData(0, PropertyValueRole, CastShadow);
|
||||||
|
|
||||||
|
mLightSizeXItem->setText(1, lcFormatValueLocalized(LightSize[0]));
|
||||||
|
mLightSizeXItem->setData(0, PropertyValueRole, LightSize[0]);
|
||||||
|
|
||||||
|
if (mLightSizeYItem)
|
||||||
|
{
|
||||||
|
mLightSizeYItem->setText(1, lcFormatValueLocalized(LightSize[1]));
|
||||||
|
mLightSizeYItem->setData(0, PropertyValueRole, LightSize[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (LightType)
|
||||||
|
{
|
||||||
|
case lcLightType::Point:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Spot:
|
||||||
|
mLightSpotConeAngleItem->setText(1, lcFormatValueLocalized(SpotConeAngle));
|
||||||
|
mLightSpotConeAngleItem->setData(0, PropertyValueRole, SpotConeAngle);
|
||||||
|
mLightSpotConeAngleItem->setData(0, PropertyRangeRole, QPointF(1.0, 180.0));
|
||||||
|
|
||||||
|
mLightSpotPenumbraAngleItem->setText(1, lcFormatValueLocalized(SpotPenumbraAngle));
|
||||||
|
mLightSpotPenumbraAngleItem->setData(0, PropertyValueRole, SpotPenumbraAngle);
|
||||||
|
mLightSpotPenumbraAngleItem->setData(0, PropertyRangeRole, QPointF(0.0, 180.0));
|
||||||
|
|
||||||
|
mLightSpotTightnessItem->setText(1, lcFormatValueLocalized(SpotTightness));
|
||||||
|
mLightSpotTightnessItem->setData(0, PropertyValueRole, SpotTightness);
|
||||||
|
mLightSpotTightnessItem->setData(0, PropertyRangeRole, QPointF(0.0, 100.0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Directional:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Area:
|
||||||
|
mLightAreaShapeItem->setText(1, lcLight::GetAreaShapeString(LightAreaShape));
|
||||||
|
mLightAreaShapeItem->setData(0, PropertyValueRole, static_cast<int>(LightAreaShape));
|
||||||
|
|
||||||
|
mLightAreaGridXItem->setText(1, QString::number(AreaGrid.x));
|
||||||
|
mLightAreaGridXItem->setData(0, PropertyValueRole, AreaGrid.x);
|
||||||
|
|
||||||
|
mLightAreaGridYItem->setText(1, QString::number(AreaGrid.y));
|
||||||
|
mLightAreaGridYItem->setData(0, PropertyValueRole, AreaGrid.y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lcLightType::Count:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLightNameItem->setText(1, Name);
|
||||||
|
mLightNameItem->setData(0, PropertyValueRole, QVariant::fromValue(Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcQPropertiesTree::SetMultiple()
|
void lcQPropertiesTree::SetMultiple()
|
||||||
|
|
|
@ -36,7 +36,8 @@ public:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PropertyTypeRole = Qt::UserRole,
|
PropertyTypeRole = Qt::UserRole,
|
||||||
PropertyValueRole
|
PropertyValueRole,
|
||||||
|
PropertyRangeRole
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PropertyType
|
enum PropertyType
|
||||||
|
@ -44,9 +45,12 @@ public:
|
||||||
PropertyGroup,
|
PropertyGroup,
|
||||||
PropertyBool,
|
PropertyBool,
|
||||||
PropertyFloat,
|
PropertyFloat,
|
||||||
|
PropertyInteger,
|
||||||
PropertyStep,
|
PropertyStep,
|
||||||
PropertyString,
|
PropertyString,
|
||||||
|
PropertyStringList,
|
||||||
PropertyColor,
|
PropertyColor,
|
||||||
|
PropertyPieceColor,
|
||||||
PropertyPart
|
PropertyPart
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,12 +59,14 @@ protected slots:
|
||||||
void slotReturnPressed();
|
void slotReturnPressed();
|
||||||
void slotSetValue(int value);
|
void slotSetValue(int value);
|
||||||
void slotColorButtonClicked();
|
void slotColorButtonClicked();
|
||||||
|
void LightColorButtonClicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
void updateColorEditor(QPushButton *editor, int value) const;
|
void updateColorEditor(QPushButton *editor, int value) const;
|
||||||
|
void UpdateLightColorEditor(QPushButton* Editor, QColor Color) const;
|
||||||
|
|
||||||
QTreeWidgetItem *addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType);
|
QTreeWidgetItem *addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType);
|
||||||
|
|
||||||
|
@ -70,49 +76,68 @@ protected:
|
||||||
void SetLight(lcObject* Focus);
|
void SetLight(lcObject* Focus);
|
||||||
void SetMultiple();
|
void SetMultiple();
|
||||||
|
|
||||||
void getPartProperties(lcPartProperties *properties);
|
lcLightType mLightType;
|
||||||
|
|
||||||
lcPropertyWidgetMode mWidgetMode;
|
lcPropertyWidgetMode mWidgetMode;
|
||||||
lcObject* mFocus;
|
lcObject* mFocus;
|
||||||
|
|
||||||
lcQPropertiesTreeDelegate *m_delegate;
|
lcQPropertiesTreeDelegate* mDelegate;
|
||||||
QIcon m_expandIcon;
|
QIcon m_expandIcon;
|
||||||
QIcon m_checkedIcon;
|
QIcon m_checkedIcon;
|
||||||
QIcon m_uncheckedIcon;
|
QIcon m_uncheckedIcon;
|
||||||
|
|
||||||
QTreeWidgetItem *partPosition;
|
QTreeWidgetItem* mPieceAttributesItem;
|
||||||
QTreeWidgetItem *partPositionX;
|
QTreeWidgetItem* partVisibility;
|
||||||
QTreeWidgetItem *partPositionY;
|
QTreeWidgetItem* partShow;
|
||||||
QTreeWidgetItem *partPositionZ;
|
QTreeWidgetItem* partHide;
|
||||||
QTreeWidgetItem *partRotation;
|
QTreeWidgetItem* partAppearance;
|
||||||
QTreeWidgetItem *partRotationX;
|
QTreeWidgetItem* mPieceColorItem;
|
||||||
QTreeWidgetItem *partRotationY;
|
QTreeWidgetItem* mPieceIdItem;
|
||||||
QTreeWidgetItem *partRotationZ;
|
|
||||||
QTreeWidgetItem *partVisibility;
|
|
||||||
QTreeWidgetItem *partShow;
|
|
||||||
QTreeWidgetItem *partHide;
|
|
||||||
QTreeWidgetItem *partAppearance;
|
|
||||||
QTreeWidgetItem *partColor;
|
|
||||||
QTreeWidgetItem *partID;
|
|
||||||
|
|
||||||
QTreeWidgetItem *cameraPosition;
|
QTreeWidgetItem* cameraPosition;
|
||||||
QTreeWidgetItem *cameraPositionX;
|
QTreeWidgetItem* cameraPositionX;
|
||||||
QTreeWidgetItem *cameraPositionY;
|
QTreeWidgetItem* cameraPositionY;
|
||||||
QTreeWidgetItem *cameraPositionZ;
|
QTreeWidgetItem* cameraPositionZ;
|
||||||
QTreeWidgetItem *cameraTarget;
|
QTreeWidgetItem* cameraTarget;
|
||||||
QTreeWidgetItem *cameraTargetX;
|
QTreeWidgetItem* cameraTargetX;
|
||||||
QTreeWidgetItem *cameraTargetY;
|
QTreeWidgetItem* cameraTargetY;
|
||||||
QTreeWidgetItem *cameraTargetZ;
|
QTreeWidgetItem* cameraTargetZ;
|
||||||
QTreeWidgetItem *cameraUp;
|
QTreeWidgetItem* cameraUp;
|
||||||
QTreeWidgetItem *cameraUpX;
|
QTreeWidgetItem* cameraUpX;
|
||||||
QTreeWidgetItem *cameraUpY;
|
QTreeWidgetItem* cameraUpY;
|
||||||
QTreeWidgetItem *cameraUpZ;
|
QTreeWidgetItem* cameraUpZ;
|
||||||
QTreeWidgetItem *cameraSettings;
|
QTreeWidgetItem* mCameraAttributesItem;
|
||||||
QTreeWidgetItem *cameraOrtho;
|
QTreeWidgetItem* mCameraProjectionItem;
|
||||||
QTreeWidgetItem *cameraFOV;
|
QTreeWidgetItem* cameraFOV;
|
||||||
QTreeWidgetItem *cameraNear;
|
QTreeWidgetItem* cameraNear;
|
||||||
QTreeWidgetItem *cameraFar;
|
QTreeWidgetItem* cameraFar;
|
||||||
QTreeWidgetItem *cameraName;
|
QTreeWidgetItem* mCameraNameItem;
|
||||||
|
|
||||||
|
QTreeWidgetItem* mLightColorItem;
|
||||||
|
QTreeWidgetItem* mLightPowerItem;
|
||||||
|
QTreeWidgetItem* mLightAttributesItem;
|
||||||
|
QTreeWidgetItem* mLightTypeItem;
|
||||||
|
QTreeWidgetItem* mLightAttenuationDistanceItem;
|
||||||
|
QTreeWidgetItem* mLightAttenuationPowerItem;
|
||||||
|
QTreeWidgetItem* mLightSpotConeAngleItem;
|
||||||
|
QTreeWidgetItem* mLightSpotPenumbraAngleItem;
|
||||||
|
QTreeWidgetItem* mLightSpotTightnessItem;
|
||||||
|
QTreeWidgetItem* mLightAreaShapeItem;
|
||||||
|
QTreeWidgetItem* mLightAreaGridXItem;
|
||||||
|
QTreeWidgetItem* mLightAreaGridYItem;
|
||||||
|
QTreeWidgetItem* mLightSizeXItem;
|
||||||
|
QTreeWidgetItem* mLightSizeYItem;
|
||||||
|
QTreeWidgetItem* mLightNameItem;
|
||||||
|
QTreeWidgetItem* mLightCastShadowItem;
|
||||||
|
|
||||||
|
QTreeWidgetItem* mPositionItem;
|
||||||
|
QTreeWidgetItem* mPositionXItem;
|
||||||
|
QTreeWidgetItem* mPositionYItem;
|
||||||
|
QTreeWidgetItem* mPositionZItem;
|
||||||
|
QTreeWidgetItem* mRotationItem;
|
||||||
|
QTreeWidgetItem* mRotationXItem;
|
||||||
|
QTreeWidgetItem* mRotationYItem;
|
||||||
|
QTreeWidgetItem* mRotationZItem;
|
||||||
};
|
};
|
||||||
|
|
||||||
class lcQPropertiesTreeDelegate : public QItemDelegate
|
class lcQPropertiesTreeDelegate : public QItemDelegate
|
||||||
|
@ -161,4 +186,3 @@ private:
|
||||||
mutable QWidget *m_editedWidget;
|
mutable QWidget *m_editedWidget;
|
||||||
mutable bool m_disablePainting;
|
mutable bool m_disablePainting;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -348,14 +348,6 @@ void lcRenderDialog::on_RenderButton_clicked()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (!LGEOPath.isEmpty())
|
|
||||||
{
|
|
||||||
Arguments.append(QString::fromLatin1("+L%1lg/").arg(LGEOPath));
|
|
||||||
Arguments.append(QString::fromLatin1("+L%1ar/").arg(LGEOPath));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
QString POVRayPath;
|
QString POVRayPath;
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -372,6 +364,29 @@ void lcRenderDialog::on_RenderButton_clicked()
|
||||||
POVRayPath = QDir::cleanPath(QCoreApplication::applicationDirPath() + QLatin1String("/povray"));
|
POVRayPath = QDir::cleanPath(QCoreApplication::applicationDirPath() + QLatin1String("/povray"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const QString POVRayDir = QFileInfo(POVRayPath).absolutePath();
|
||||||
|
const QString IncludePath = QDir::cleanPath(POVRayDir + "/include");
|
||||||
|
if (QFileInfo(IncludePath).exists())
|
||||||
|
Arguments.append(QString("+L\"%1\"").arg(IncludePath));
|
||||||
|
const QString IniPath = QDir::cleanPath(POVRayDir + "/ini");
|
||||||
|
if (QFileInfo(IniPath).exists())
|
||||||
|
Arguments.append(QString("+L\"%1\"").arg(IniPath));
|
||||||
|
if (lcGetActiveProject()->GetModels()[0]->GetPOVRayOptions().UseLGEO) {
|
||||||
|
const QString LGEOPath = lcGetProfileString(LC_PROFILE_POVRAY_LGEO_PATH);
|
||||||
|
if (QFileInfo(LGEOPath).exists())
|
||||||
|
{
|
||||||
|
const QString LgPath = QDir::cleanPath(LGEOPath + "/lg");
|
||||||
|
if (QFileInfo(LgPath).exists())
|
||||||
|
Arguments.append(QString("+L\"%1\"").arg(LgPath));
|
||||||
|
const QString ArPath = QDir::cleanPath(LGEOPath + "/ar");
|
||||||
|
if (QFileInfo(ArPath).exists())
|
||||||
|
Arguments.append(QString("+L\"%1\"").arg(ArPath));
|
||||||
|
const QString StlPath = QDir::cleanPath(LGEOPath + "/stl");
|
||||||
|
if (QFileInfo(StlPath).exists())
|
||||||
|
Arguments.append(QString("+L\"%1\"").arg(StlPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mProcess = new lcRenderProcess(this);
|
mProcess = new lcRenderProcess(this);
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
connect(mProcess, SIGNAL(readyReadStandardError()), this, SLOT(ReadStdErr()));
|
connect(mProcess, SIGNAL(readyReadStandardError()), this, SLOT(ReadStdErr()));
|
||||||
|
@ -882,11 +897,16 @@ void lcRenderDialog::on_OutputBrowseButton_clicked()
|
||||||
|
|
||||||
void lcRenderDialog::on_RenderOutputButton_clicked()
|
void lcRenderDialog::on_RenderOutputButton_clicked()
|
||||||
{
|
{
|
||||||
const QString RenderType = mCommand == POVRAY_RENDER ? QLatin1String("POV-Ray") : QLatin1String("Blender");
|
QFileInfo FileInfo(GetStdErrFileName());
|
||||||
QFileInfo FileInfo(GetStdOutFileName());
|
QString Message = tr("POV-Ray standard error file not found: %1.").arg(FileInfo.absoluteFilePath());
|
||||||
|
if (mCommand == BLENDER_RENDER)
|
||||||
|
{
|
||||||
|
FileInfo.setFile(GetStdOutFileName());
|
||||||
|
Message = tr("Blender standard output file not found: %1.").arg(FileInfo.absoluteFilePath());
|
||||||
|
}
|
||||||
if (!FileInfo.exists())
|
if (!FileInfo.exists())
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, tr("Error"), tr("%1 Standard output file not found: %2.").arg(RenderType).arg(FileInfo.absoluteFilePath()));
|
QMessageBox::warning(this, tr("Error"), Message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
BIN
resources/action_arealight.png
Normal file
BIN
resources/action_arealight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
resources/action_arealight_16.png
Normal file
BIN
resources/action_arealight_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 877 B |
BIN
resources/action_sunlight.png
Normal file
BIN
resources/action_sunlight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
resources/action_sunlight_16.png
Normal file
BIN
resources/action_sunlight_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 720 B |
BIN
resources/cursor_arealight.png
Normal file
BIN
resources/cursor_arealight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 417 B |
BIN
resources/cursor_sunlight.png
Normal file
BIN
resources/cursor_sunlight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 428 B |
|
@ -5602,7 +5602,7 @@ Informace o tom, jak stáhnout a nainstalovat knihovnu, naleznete na adrese http
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||||
<source>New SpotLight</source>
|
<source>New Spotlight</source>
|
||||||
<translation>Nový zdroj osvětlení</translation>
|
<translation>Nový zdroj osvětlení</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -5501,7 +5501,7 @@ Bitte lesen sie unter https://www.leocad.org nach wie man eine Bibliothek herunt
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||||
<source>New SpotLight</source>
|
<source>New Spotlight</source>
|
||||||
<translation>Neues Scheinwerferlicht</translation>
|
<translation>Neues Scheinwerferlicht</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -5577,7 +5577,7 @@ Por favor, visita https://www.leocad.org para saber cómo descargar e instalar u
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||||
<source>New SpotLight</source>
|
<source>New Spotlight</source>
|
||||||
<translation>nuevo foco</translation>
|
<translation>nuevo foco</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -5485,7 +5485,7 @@ SVP visitez https://www.leocad.org pour apprendre comment télécharger et insta
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||||
<source>New SpotLight</source>
|
<source>New Spotlight</source>
|
||||||
<translation>Nouvelle lumière projecteur</translation>
|
<translation>Nouvelle lumière projecteur</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -5412,7 +5412,7 @@ Veja https://www.leocad.org para saber como descarragar e instalar uma bibliotec
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||||
<source>New SpotLight</source>
|
<source>New Spotlight</source>
|
||||||
<translation>Novo Projector</translation>
|
<translation>Novo Projector</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -5477,7 +5477,7 @@ Please visit https://www.leocad.org for information on how to download and insta
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||||
<source>New SpotLight</source>
|
<source>New Spotlight</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
|
Loading…
Reference in a new issue