mirror of
https://github.com/leozide/leocad
synced 2025-01-13 08:01:38 +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;
|
||||
|
||||
if (mPositionKeys.GetSize() > 1)
|
||||
mPositionKeys.SaveKeysLDraw(Stream, "CAMERA POSITION_KEY ");
|
||||
else
|
||||
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;
|
||||
SaveAttribute(Stream, mPosition, mPositionKeys, "CAMERA", "POSITION");
|
||||
SaveAttribute(Stream, mTargetPosition, mTargetPositionKeys, "CAMERA", "TARGET_POSITION");
|
||||
SaveAttribute(Stream, mUpVector, mUpVectorKeys, "CAMERA", "UP_VECTOR");
|
||||
|
||||
Stream << QLatin1String("0 !LEOCAD CAMERA ");
|
||||
|
||||
|
@ -176,7 +165,7 @@ bool lcCamera::ParseLDrawLine(QTextStream& Stream)
|
|||
Stream >> Token;
|
||||
|
||||
if (Token == QLatin1String("HIDDEN"))
|
||||
SetHidden(true);
|
||||
SetHidden(true);
|
||||
else if (Token == QLatin1String("ORTHOGRAPHIC"))
|
||||
SetOrtho(true);
|
||||
else if (Token == QLatin1String("FOV"))
|
||||
|
@ -185,27 +174,12 @@ bool lcCamera::ParseLDrawLine(QTextStream& Stream)
|
|||
Stream >> m_zNear;
|
||||
else if (Token == QLatin1String("ZFAR"))
|
||||
Stream >> m_zFar;
|
||||
else if (Token == QLatin1String("POSITION"))
|
||||
{
|
||||
Stream >> mPosition[0] >> mPosition[1] >> mPosition[2];
|
||||
mPositionKeys.ChangeKey(mPosition, 1, true);
|
||||
}
|
||||
else if (Token == QLatin1String("TARGET_POSITION"))
|
||||
{
|
||||
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 (LoadAttribute(Stream, Token, mPosition, mPositionKeys, "POSITION"))
|
||||
continue;
|
||||
else if (LoadAttribute(Stream, Token, mTargetPosition, mTargetPositionKeys, "TARGET_POSITION"))
|
||||
continue;
|
||||
else if (LoadAttribute(Stream, Token, mUpVector, mUpVectorKeys, "UP_VECTOR"))
|
||||
continue;
|
||||
else if (Token == QLatin1String("NAME"))
|
||||
{
|
||||
mName = Stream.readAll().trimmed();
|
||||
|
|
|
@ -202,7 +202,7 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
@ -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")},
|
||||
/* 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")},
|
||||
/* 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")},
|
||||
/* 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)},
|
||||
|
@ -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")},
|
||||
|
||||
/*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")},
|
||||
/*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.")},
|
||||
/*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.")},
|
||||
|
||||
/*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")},
|
||||
/* 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")},
|
||||
/* 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")},
|
||||
/* 04 LBL_DISPLAY_LOGO */ {"displaylogo", "1", QObject::tr("Display Logo"), QObject::tr("Display the logo on the stud")},
|
||||
/* 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)},
|
||||
/* 06 LBL_IMPORT_EDGES */ {"importedges", "0", QObject::tr("Import Edges"), QObject::tr("Import LDraw edges as edges")},
|
||||
/* 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)},
|
||||
/* 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")},
|
||||
/* 09 LBL_MAKE_GAPS */ {"makegaps", "1", QObject::tr("Make Gaps"), QObject::tr("Make small gaps between bricks. A small gap is more realistic")},
|
||||
/* 10 LBL_META_BFC */ {"metabfc", "1", QObject::tr("BFC"), QObject::tr("Process LDraw Back Face Culling meta commands")},
|
||||
/* 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")},
|
||||
/* 12 LBL_META_GROUP */ {"metagroup", "1", QObject::tr("GROUP Command"), QObject::tr("Process GROUP meta commands")},
|
||||
/* 13 LBL_META_PAUSE */ {"metapause", "0", QObject::tr("PAUSE Command"), QObject::tr("Not implemented")},
|
||||
/* 14 LBL_META_PRINT_WRITE */ {"metaprintwrite", "0", QObject::tr("PRINT/WRITE Command"), QObject::tr("Prints PRINT/WRITE META commands to the system console.")},
|
||||
/* 15 LBL_META_SAVE */ {"metasave", "0", QObject::tr("SAVE Command"), QObject::tr("Not implemented")},
|
||||
/* 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")},
|
||||
/* 17 LBL_META_STEP_GROUPS */ {"metastepgroups", "0", QObject::tr("STEP Groups"), QObject::tr("Create collection for individual steps")},
|
||||
/* 18 LBL_META_TEXMAP */ {"metatexmap", "1", QObject::tr("TEXMAP and DATA Command"), QObject::tr("Process TEXMAP and DATA meta commands")},
|
||||
/* 19 LBL_NO_STUDS */ {"nostuds", "0", QObject::tr("No Studs"), QObject::tr("Don't import studs")},
|
||||
/* 20 LBL_OVERWRITE_IMAGE_MM */ {"overwriteimage", "1", QObject::tr("Overwrite Image"), QObject::tr("Specify whether to overwrite an existing rendered image file")},
|
||||
/* 21 LBL_POSITION_CAMERA_MM */ {"positioncamera", "1", QObject::tr("Position Camera"), QObject::tr("Position the camera to show the whole model")},
|
||||
/* 22 LBL_PARENT_TO_EMPTY */ {"parenttoempty", "1", QObject::tr("Parent To Empty"), QObject::tr("Parent the model to an empty")},
|
||||
/* 23 LBL_PREFER_STUDIO */ {"preferstudio", "0", QObject::tr("Prefer Stud.io Library"), QObject::tr("Search for parts in Stud.io library first")},
|
||||
/* 24 LBL_PREFER_UNOFFICIAL */ {"preferunofficial", "0", QObject::tr("Prefer Unofficial Parts"), QObject::tr("Search for unofficial parts first")},
|
||||
/* 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")},
|
||||
#ifdef Q_OS_LINUX
|
||||
/* 03 LBL_CASE_SENSITIVE_FILESYSTEM */ {"casesensitivefilesystem", "1", QObject::tr("Case-sensitive Filesystem"),QObject::tr("Filesystem is case sensitive. Defaults to true on Linux.")},
|
||||
#else
|
||||
/* 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.")},
|
||||
#endif
|
||||
/* 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")},
|
||||
/* 05 LBL_DISPLAY_LOGO */ {"displaylogo", "1", QObject::tr("Display Logo"), QObject::tr("Display the logo on the stud")},
|
||||
/* 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)},
|
||||
/* 07 LBL_IMPORT_EDGES */ {"importedges", "0", QObject::tr("Import Edges"), QObject::tr("Import LDraw edges as edges")},
|
||||
/* 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)},
|
||||
/* 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")},
|
||||
/* 10 LBL_MAKE_GAPS */ {"makegaps", "1", QObject::tr("Make Gaps"), QObject::tr("Make small gaps between bricks. A small gap is more realistic")},
|
||||
/* 11 LBL_META_BFC */ {"metabfc", "1", QObject::tr("BFC"), QObject::tr("Process LDraw Back Face Culling meta commands")},
|
||||
/* 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")},
|
||||
/* 13 LBL_META_GROUP */ {"metagroup", "1", QObject::tr("GROUP Command"), QObject::tr("Process GROUP meta commands")},
|
||||
/* 14 LBL_META_PAUSE */ {"metapause", "0", QObject::tr("PAUSE Command"), QObject::tr("Not implemented")},
|
||||
/* 15 LBL_META_PRINT_WRITE */ {"metaprintwrite", "0", QObject::tr("PRINT/WRITE Command"), QObject::tr("Prints PRINT/WRITE META commands to the system console.")},
|
||||
/* 16 LBL_META_SAVE */ {"metasave", "0", QObject::tr("SAVE Command"), QObject::tr("Not implemented")},
|
||||
/* 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")},
|
||||
/* 18 LBL_META_STEP_GROUPS */ {"metastepgroups", "0", QObject::tr("STEP Groups"), QObject::tr("Create collection for individual steps")},
|
||||
/* 19 LBL_META_TEXMAP */ {"metatexmap", "1", QObject::tr("TEXMAP and DATA Command"), QObject::tr("Process TEXMAP and DATA meta commands")},
|
||||
/* 20 LBL_NO_STUDS */ {"nostuds", "0", QObject::tr("No Studs"), QObject::tr("Don't import studs")},
|
||||
/* 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")},
|
||||
/* 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.")},
|
||||
|
@ -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")},
|
||||
/* 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")},
|
||||
/* 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")},
|
||||
/* 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")},
|
||||
/* 37 LBL_TRIANGULATE */ {"triangulate", "0", QObject::tr("Triangulate Faces"), QObject::tr("Triangulate all faces")},
|
||||
/* 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")},
|
||||
/* 39 LBL_USE_FREESTYLE_EDGES */ {"usefreestyleedges", "0", QObject::tr("Use Freestyle Edges"), QObject::tr("Render LDraw edges using freestyle")},
|
||||
/* 40 LBL_VERBOSE_MM */ {"verbose", "1", QObject::tr("Verbose output"), QObject::tr("Output all messages while working, else only show warnings and errors")},
|
||||
/* 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_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_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")},
|
||||
|
||||
/* 41/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")},
|
||||
/* 43/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")},
|
||||
/* 45/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")},
|
||||
/* 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")},
|
||||
/* 48/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.")},
|
||||
/* 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.")},
|
||||
/* 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.")},
|
||||
/* 52/11 LBL_STARTING_STEP_FRAME */ {"startingstepframe", "1", QObject::tr("Starting Step Frame"), QObject::tr("Frame to add the first STEP meta command")},
|
||||
/* 40/00 LBL_BEVEL_SEGMENTS */ {"bevelsegments", "4", QObject::tr("Bevel Segments"), QObject::tr("Bevel segments")},
|
||||
/* 41/01 LBL_BEVEL_WEIGHT */ {"bevelweight", "0.3", QObject::tr("Bevel Weight"), QObject::tr("Bevel weight")},
|
||||
/* 42/02 LBL_BEVEL_WIDTH_MM */ {"bevelwidth", "0.3", QObject::tr("Bevel Width"), QObject::tr("Width of the bevelled edges")},
|
||||
/* 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")},
|
||||
/* 44/04 LBL_FRAMES_PER_STEP */ {"framesperstep", "3", QObject::tr("Frames Per Step"), QObject::tr("Frames per step")},
|
||||
/* 45/05 LBL_GAP_SCALE */ {"gapscale", "0.997", QObject::tr("Gap Scale"), QObject::tr("Scale individual parts by this much to create the gap")},
|
||||
/* 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")},
|
||||
/* 47/07 LBL_MERGE_DISTANCE */ {"mergedistance", "0.05", QObject::tr("Merge Distance"), QObject::tr("Maximum distance between elements to merge")},
|
||||
/* 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.")},
|
||||
/* 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.")},
|
||||
/* 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.")},
|
||||
/* 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")},
|
||||
/* 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)")},
|
||||
/* 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")},
|
||||
/* 56/03 LBL_GAP_TARGET */ {"gaptarget", "object", QObject::tr("Gap Target"), QObject::tr("Whether to scale the object data or mesh data")},
|
||||
/* 57/04 LBL_RESOLUTION_MM */ {"resolution", "Standard", QObject::tr("Resolution"), QObject::tr("Resolution of part primitives, ie. how much geometry they have")},
|
||||
/* 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")}
|
||||
/* 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")},
|
||||
/* 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)")},
|
||||
/* 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)")},
|
||||
/* 55/03 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")}
|
||||
};
|
||||
|
||||
lcBlenderPreferences::ComboItems lcBlenderPreferences::mComboItemsMM [NUM_COMBO_ITEMS_MM] =
|
||||
{
|
||||
/* 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")},
|
||||
/* 02 LBL_GAP_SCALE_STRATEGY */ {"object|constraint", QObject::tr("Gap applied directly to object|Gap scaled to adjust to gaps between parts")},
|
||||
/* 03 LBL_GAP_TARGET */ {"object|mesh", QObject::tr("Scale object data|Scale mesh data")},
|
||||
/* 04 LBL_RESOLUTION_MM */ {"Low|Standard|High", QObject::tr("Low Resolution Primitives|Standard Primitives|High Resolution Primitives")},
|
||||
/* 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")}
|
||||
/* 02 LBL_COLOUR_STRATEGY */ {"material|vertex_colors", QObject::tr("Material|Vertex Colors")},
|
||||
/* 03 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")}
|
||||
};
|
||||
|
||||
lcBlenderPreferences* gAddonPreferences;
|
||||
|
@ -441,31 +442,40 @@ lcBlenderPreferences::lcBlenderPreferences(int Width, int Height, double Scale,
|
|||
mAddonGridLayout = new QGridLayout(BlenderAddonVersionBox);
|
||||
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);
|
||||
mAddonGridLayout->addWidget(mAddonVersionLabel,0,0);
|
||||
mAddonGridLayout->addWidget(mAddonVersionLabel,1,0);
|
||||
|
||||
mAddonVersionEdit = new QLineEdit(BlenderAddonVersionBox);
|
||||
mAddonVersionEdit->setToolTip(tr("%1 Blender LDraw import and image renderer addon").arg(LC_PRODUCTNAME_STR));
|
||||
mAddonVersionEdit->setPalette(ReadOnlyPalette);
|
||||
mAddonVersionEdit->setReadOnly(true);
|
||||
mAddonGridLayout->addWidget(mAddonVersionEdit,0,1);
|
||||
mAddonGridLayout->addWidget(mAddonVersionEdit,1,1);
|
||||
mAddonGridLayout->setColumnStretch(1,1/*1 is greater than 0 (default)*/);
|
||||
|
||||
mAddonUpdateButton = new QPushButton(tr("Update"), BlenderAddonVersionBox);
|
||||
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()));
|
||||
|
||||
mAddonStdOutButton = new QPushButton(tr("Output..."), BlenderAddonVersionBox);
|
||||
mAddonStdOutButton->setToolTip(tr("Open the standrd output log"));
|
||||
mAddonStdOutButton->setEnabled(false);
|
||||
mAddonGridLayout->addWidget(mAddonStdOutButton,0,3);
|
||||
mAddonGridLayout->addWidget(mAddonStdOutButton,1,3);
|
||||
connect(mAddonStdOutButton, SIGNAL(clicked(bool)), this, SLOT(GetStandardOutput()));
|
||||
|
||||
mModulesBox = new QGroupBox(tr("Enabled Addon Modules"),mContent);
|
||||
QHBoxLayout* ModulesLayout = new QHBoxLayout(mModulesBox);
|
||||
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->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)
|
||||
{
|
||||
if (LocalVersion.isEmpty())
|
||||
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)
|
||||
if (lcGetProfileInt(LC_PROFILE_BLENDER_ADDON_VERSION_CHECK))
|
||||
{
|
||||
AddonStatus = tr("Blender addon setup cancelled");
|
||||
AddonAction = ADDON_CANCEL;
|
||||
if (LocalVersion.isEmpty())
|
||||
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;
|
||||
}
|
||||
|
@ -2586,7 +2603,9 @@ void lcBlenderPreferences::SaveSettings()
|
|||
continue;
|
||||
Key = mBlenderPaths[LblIdx].key;
|
||||
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++)
|
||||
|
@ -2608,7 +2627,9 @@ void lcBlenderPreferences::SaveSettings()
|
|||
}
|
||||
|
||||
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)));
|
||||
|
@ -2625,7 +2646,9 @@ void lcBlenderPreferences::SaveSettings()
|
|||
continue;
|
||||
Key = mBlenderPaths[LblIdx].key_mm;
|
||||
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++)
|
||||
|
@ -2644,7 +2667,9 @@ void lcBlenderPreferences::SaveSettings()
|
|||
}
|
||||
|
||||
Key = mBlenderSettingsMM[LblIdx].key;
|
||||
Settings.setValue(Key, QVariant(Value));
|
||||
|
||||
if (Settings.contains(Key))
|
||||
Settings.setValue(Key, QVariant(Value));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -237,30 +237,30 @@ private:
|
|||
LBL_ADD_ENVIRONMENT_MM, // 0 QCheckBox
|
||||
LBL_BEVEL_EDGES_MM, // 1 QCheckBox
|
||||
LBL_BLEND_FILE_TRUSTED_MM, // 2 QCheckBox
|
||||
LBL_CROP_IMAGE_MM, // 3 QCheckBox
|
||||
LBL_DISPLAY_LOGO, // 4 QCheckBox
|
||||
LBL_IMPORT_CAMERAS_MM, // 5 QCheckBox
|
||||
LBL_IMPORT_EDGES, // 6 QCheckBox
|
||||
LBL_CASE_SENSITIVE_FILESYSTEM, // 3 QCheckBox
|
||||
LBL_CROP_IMAGE_MM, // 4 QCheckBox
|
||||
LBL_DISPLAY_LOGO, // 5 QCheckBox
|
||||
LBL_IMPORT_CAMERAS_MM, // 6 QCheckBox
|
||||
NUM_COMBO_ITEMS_MM, // 7
|
||||
LBL_IMPORT_LIGHTS_MM = NUM_COMBO_ITEMS_MM, // 7 QCheckBox
|
||||
LBL_KEEP_ASPECT_RATIO_MM, // 8 QCheckBox
|
||||
LBL_MAKE_GAPS, // 9 QCheckBox
|
||||
LBL_META_BFC, // 10 QCheckBox
|
||||
LBL_META_CLEAR, // 11 QCheckBox
|
||||
LBL_META_GROUP, // 12 QCheckBox
|
||||
LBL_META_PAUSE, // 13 QCheckBox
|
||||
LBL_META_PRINT_WRITE, // 14 QCheckBox
|
||||
LBL_META_SAVE, // 15 QCheckBox
|
||||
LBL_META_STEP, // 16 QCheckBox
|
||||
LBL_META_STEP_GROUPS, // 17 QCheckBox
|
||||
LBL_META_TEXMAP, // 18 QCheckBox
|
||||
LBL_NO_STUDS, // 19 QCheckBox
|
||||
LBL_OVERWRITE_IMAGE_MM, // 20 QCheckBox
|
||||
LBL_POSITION_CAMERA_MM, // 21 QCheckBox
|
||||
LBL_PARENT_TO_EMPTY, // 22 QCheckBox
|
||||
LBL_PREFER_STUDIO, // 23 QCheckBox
|
||||
LBL_PREFER_UNOFFICIAL, // 24 QCheckBox
|
||||
LBL_PRESERVE_HIERARCHY, // 25 QCheckBox
|
||||
LBL_IMPORT_EDGES = NUM_COMBO_ITEMS_MM, // 7 QCheckBox
|
||||
LBL_IMPORT_LIGHTS_MM, // 8 QCheckBox
|
||||
LBL_KEEP_ASPECT_RATIO_MM, // 9 QCheckBox
|
||||
LBL_MAKE_GAPS, // 10 QCheckBox
|
||||
LBL_META_BFC, // 11 QCheckBox
|
||||
LBL_META_CLEAR, // 12 QCheckBox
|
||||
LBL_META_GROUP, // 13 QCheckBox
|
||||
LBL_META_PAUSE, // 14 QCheckBox
|
||||
LBL_META_PRINT_WRITE, // 15 QCheckBox
|
||||
LBL_META_SAVE, // 16 QCheckBox
|
||||
LBL_META_STEP, // 17 QCheckBox
|
||||
LBL_META_STEP_GROUPS, // 18 QCheckBox
|
||||
LBL_META_TEXMAP, // 19 QCheckBox
|
||||
LBL_NO_STUDS, // 20 QCheckBox
|
||||
LBL_OVERWRITE_IMAGE_MM, // 21 QCheckBox
|
||||
LBL_POSITION_CAMERA_MM, // 22 QCheckBox
|
||||
LBL_PARENT_TO_EMPTY, // 23 QCheckBox
|
||||
LBL_PREFER_STUDIO, // 24 QCheckBox
|
||||
LBL_PREFER_UNOFFICIAL, // 25 QCheckBox
|
||||
LBL_PROFILE, // 26 QCheckBox
|
||||
LBL_RECALCULATE_NORMALS, // 27 QCheckBox
|
||||
LBL_REMOVE_DOUBLES_MM, // 28 QCheckBox
|
||||
|
@ -270,32 +270,30 @@ private:
|
|||
LBL_SET_TIMELINE_MARKERS, // 32 QCheckBox
|
||||
LBL_SHADE_SMOOTH, // 33 QCheckBox
|
||||
LBL_TRANSPARENT_BACKGROUND_MM, // 34 QCheckBox
|
||||
LBL_TREAT_MODELS_WITH_SUBPARTS_AS_PARTS, // 35 QCheckBox
|
||||
LBL_TREAT_SHORTCUT_AS_MODEL, // 36 QCheckBox
|
||||
LBL_TRIANGULATE, // 37 QCheckBox
|
||||
LBL_USE_ARCHIVE_LIBRARY_MM, // 38 QCheckBox
|
||||
LBL_USE_FREESTYLE_EDGES, // 39 QCheckBox
|
||||
LBL_VERBOSE_MM, // 40 QCheckBox
|
||||
LBL_TREAT_SHORTCUT_AS_MODEL, // 35 QCheckBox
|
||||
LBL_TRIANGULATE, // 36 QCheckBox
|
||||
LBL_USE_ARCHIVE_LIBRARY_MM, // 37 QCheckBox
|
||||
LBL_USE_FREESTYLE_EDGES, // 38 QCheckBox
|
||||
LBL_VERBOSE_MM, // 39 QCheckBox
|
||||
|
||||
LBL_BEVEL_SEGMENTS, // 41/ 0 QLineEdit
|
||||
LBL_BEVEL_WEIGHT, // 42/ 1 QLineEdit
|
||||
LBL_BEVEL_WIDTH_MM, // 43/ 2 QLineEdit
|
||||
LBL_CAMERA_BORDER_PERCENT_MM, // 44/ 3 QLineEdit
|
||||
LBL_FRAMES_PER_STEP, // 45/ 4 QLineEdit
|
||||
LBL_GAP_SCALE, // 46/ 5 QLineEdit
|
||||
LBL_IMPORT_SCALE, // 47/ 6 QLineEdit
|
||||
LBL_MERGE_DISTANCE, // 48/ 7 QLineEdit
|
||||
LBL_RENDER_PERCENTAGE_MM, // 49/ 8 QLineEdit
|
||||
LBL_RESOLUTION_WIDTH, // 50/ 9 QLineEdit
|
||||
LBL_RESOLUTION_HEIGHT, // 51/10 QLineEdit
|
||||
LBL_STARTING_STEP_FRAME, // 52/11 QLineEdit
|
||||
LBL_BEVEL_SEGMENTS, // 40/ 0 QLineEdit
|
||||
LBL_BEVEL_WEIGHT, // 41/ 1 QLineEdit
|
||||
LBL_BEVEL_WIDTH_MM, // 42/ 2 QLineEdit
|
||||
LBL_CAMERA_BORDER_PERCENT_MM, // 43/ 3 QLineEdit
|
||||
LBL_FRAMES_PER_STEP, // 44/ 4 QLineEdit
|
||||
LBL_GAP_SCALE, // 45/ 5 QLineEdit
|
||||
LBL_IMPORT_SCALE, // 46/ 6 QLineEdit
|
||||
LBL_MERGE_DISTANCE, // 47/ 7 QLineEdit
|
||||
LBL_RENDER_PERCENTAGE_MM, // 48/ 8 QLineEdit
|
||||
LBL_RESOLUTION_WIDTH, // 49/ 9 QLineEdit
|
||||
LBL_RESOLUTION_HEIGHT, // 50/10 QLineEdit
|
||||
LBL_STARTING_STEP_FRAME, // 51/11 QLineEdit
|
||||
|
||||
LBL_CHOSEN_LOGO, // 53/ 0 QComboBox
|
||||
LBL_COLOUR_SCHEME_MM, // 54/ 1 QComboBox
|
||||
LBL_GAP_SCALE_STRATEGY, // 55/ 2 QComboBox
|
||||
LBL_GAP_TARGET, // 56/ 3 QComboBox
|
||||
LBL_RESOLUTION_MM, // 57/ 4 QComboBox
|
||||
LBL_SMOOTH_TYPE, // 58/ 5 QComboBox
|
||||
LBL_CHOSEN_LOGO, // 52/ 0 QComboBox
|
||||
LBL_COLOUR_SCHEME_MM, // 53/ 1 QComboBox
|
||||
LBL_COLOUR_STRATEGY, // 54/ 2 QComboBox
|
||||
LBL_RESOLUTION_MM, // 55/ 3 QComboBox
|
||||
LBL_SMOOTH_TYPE, // 56/ 4 QComboBox
|
||||
|
||||
NUM_SETTINGS_MM
|
||||
};
|
||||
|
@ -311,42 +309,41 @@ private:
|
|||
CTL_COLOUR_SCHEME_COMBO_MM = CTL_BEVEL_EDGES_BOX_MM, // 1
|
||||
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_CROP_IMAGE_BOX_MM, // 3
|
||||
CTL_CAMERA_BORDER_PERCENT_EDIT_MM = CTL_CROP_IMAGE_BOX_MM, // 3
|
||||
CTL_GAP_TARGET_COMBO = CTL_CROP_IMAGE_BOX_MM, // 3
|
||||
CTL_DISPLAY_LOGO_BOX, // 4
|
||||
CTL_FRAMES_PER_STEP_EDIT = CTL_DISPLAY_LOGO_BOX, // 4
|
||||
CTL_RESOLUTION_COMBO_MM = CTL_DISPLAY_LOGO_BOX, // 4
|
||||
CTL_IMPORT_CAMERAS_BOX_MM, // 5
|
||||
CTL_GAP_SCALE_EDIT = CTL_IMPORT_CAMERAS_BOX_MM, // 5
|
||||
CTL_SMOOTH_TYPE_COMBO = CTL_IMPORT_CAMERAS_BOX_MM, // 5
|
||||
CTL_IMPORT_EDGES_BOX, // 6
|
||||
CTL_IMPORT_SCALE_EDIT = CTL_IMPORT_EDGES_BOX, // 6
|
||||
CTL_IMPORT_LIGHTS_BOX_MM, // 7
|
||||
CTL_MERGE_DISTANCE_EDIT = CTL_IMPORT_LIGHTS_BOX_MM, // 7
|
||||
CTL_KEEP_ASPECT_RATIO_BOX_MM, // 8
|
||||
CTL_RENDER_PERCENTAGE_EDIT_MM = CTL_KEEP_ASPECT_RATIO_BOX_MM, // 8
|
||||
CTL_MAKE_GAPS_BOX, // 9
|
||||
CTL_RESOLUTION_WIDTH_EDIT = CTL_MAKE_GAPS_BOX, // 9
|
||||
CTL_META_BFC_BOX, // 10
|
||||
CTL_RESOLUTION_HEIGHT_EDIT = CTL_META_BFC_BOX, // 10
|
||||
CTL_META_CLEAR_BOX, // 11
|
||||
CTL_STARTING_STEP_FRAME_EDIT = CTL_META_CLEAR_BOX, // 11
|
||||
CTL_META_GROUP_BOX, // 12
|
||||
CTL_META_PAUSE_BOX, // 13
|
||||
CTL_META_PRINT_WRITE_BOX, // 14
|
||||
CTL_META_SAVE_BOX, // 15
|
||||
CTL_META_STEP_BOX, // 16
|
||||
CTL_META_STEP_GROUPS_BOX, // 17
|
||||
CTL_META_TEXMAP_BOX, // 18
|
||||
CTL_NO_STUDS_BOX, // 19
|
||||
CTL_POSITION_CAMERA_BOX_MM, // 10
|
||||
CTL_OVERWRITE_IMAGE_BOX_MM, // 21
|
||||
CTL_PARENT_TO_EMPTY_BOX, // 22
|
||||
CTL_PREFER_STUDIO_BOX, // 23
|
||||
CTL_PREFER_UNOFFICIAL_BOX, // 24
|
||||
CTL_PRESERVE_HIERARCHY_BOX, // 25
|
||||
CTL_COLOUR_STRATEGY_COMBO = CTL_BLEND_FILE_TRUSTED_BOX_MM,// 2
|
||||
CTL_CASE_SENSITIVE_FILESYSTEM_BOX, // 3
|
||||
CTL_CAMERA_BORDER_PERCENT_EDIT_MM = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
|
||||
CTL_RESOLUTION_COMBO_MM = CTL_CASE_SENSITIVE_FILESYSTEM_BOX,// 3
|
||||
CTL_CROP_IMAGE_BOX_MM, // 4
|
||||
CTL_FRAMES_PER_STEP_EDIT = CTL_CROP_IMAGE_BOX_MM, // 4
|
||||
CTL_SMOOTH_TYPE_COMBO = CTL_CROP_IMAGE_BOX_MM, // 4
|
||||
CTL_DISPLAY_LOGO_BOX, // 5
|
||||
CTL_GAP_SCALE_EDIT = CTL_DISPLAY_LOGO_BOX, // 5
|
||||
CTL_IMPORT_CAMERAS_BOX_MM, // 6
|
||||
CTL_IMPORT_SCALE_EDIT = CTL_IMPORT_CAMERAS_BOX_MM, // 6
|
||||
CTL_IMPORT_EDGES_BOX, // 7
|
||||
CTL_MERGE_DISTANCE_EDIT = CTL_IMPORT_EDGES_BOX, // 7
|
||||
CTL_IMPORT_LIGHTS_BOX_MM, // 8
|
||||
CTL_RENDER_PERCENTAGE_EDIT_MM = CTL_IMPORT_LIGHTS_BOX_MM, // 8
|
||||
CTL_KEEP_ASPECT_RATIO_BOX_MM, // 9
|
||||
CTL_RESOLUTION_WIDTH_EDIT = CTL_KEEP_ASPECT_RATIO_BOX_MM, // 9
|
||||
CTL_MAKE_GAPS_BOX, // 10
|
||||
CTL_RESOLUTION_HEIGHT_EDIT = CTL_MAKE_GAPS_BOX, // 10
|
||||
CTL_META_BFC_BOX, // 11
|
||||
CTL_STARTING_STEP_FRAME_EDIT = CTL_META_BFC_BOX, // 11
|
||||
CTL_META_CLEAR_BOX, // 12
|
||||
CTL_META_GROUP_BOX, // 13
|
||||
CTL_META_PAUSE_BOX, // 14
|
||||
CTL_META_PRINT_WRITE_BOX, // 15
|
||||
CTL_META_SAVE_BOX, // 16
|
||||
CTL_META_STEP_BOX, // 17
|
||||
CTL_META_STEP_GROUPS_BOX, // 18
|
||||
CTL_META_TEXMAP_BOX, // 19
|
||||
CTL_NO_STUDS_BOX, // 20
|
||||
CTL_POSITION_CAMERA_BOX_MM, // 21
|
||||
CTL_OVERWRITE_IMAGE_BOX_MM, // 22
|
||||
CTL_PARENT_TO_EMPTY_BOX, // 23
|
||||
CTL_PREFER_STUDIO_BOX, // 24
|
||||
CTL_PREFER_UNOFFICIAL_BOX, // 25
|
||||
CTL_PROFILE_BOX, // 26
|
||||
CTL_RECALCULATE_NORMALS_BOX, // 27
|
||||
CTL_REMOVE_DOUBLES_BOX_MM, // 28
|
||||
|
@ -356,12 +353,11 @@ private:
|
|||
CTL_SET_TIMELINE_MARKERS_BOX, // 32
|
||||
CTL_SHADE_SMOOTH_BOX, // 33
|
||||
CTL_TRANSPARENT_BACKGROUND_BOX_MM, // 34
|
||||
CTL_TREAT_MODELS_WITH_SUBPARTS_AS_PARTS_BOX, // 35
|
||||
CTL_TREAT_SHORTCUT_AS_MODEL_BOX, // 36
|
||||
CTL_TRIANGULATE_BOX, // 37
|
||||
CTL_USE_ARCHIVE_LIBRARY_BOX_MM, // 38
|
||||
CTL_USE_FREESTYLE_EDGES_BOX, // 39
|
||||
CTL_VERBOSE_BOX_MM // 40
|
||||
CTL_TREAT_SHORTCUT_AS_MODEL_BOX, // 35
|
||||
CTL_TRIANGULATE_BOX, // 36
|
||||
CTL_USE_ARCHIVE_LIBRARY_BOX_MM, // 37
|
||||
CTL_USE_FREESTYLE_EDGES_BOX, // 38
|
||||
CTL_VERBOSE_BOX_MM // 39
|
||||
};
|
||||
|
||||
enum BlenderBrickType
|
||||
|
|
|
@ -85,6 +85,8 @@ static std::vector<lcColor> lcParseColorFile(lcFile& File)
|
|||
|
||||
Color.Code = ~0U;
|
||||
Color.Translucent = false;
|
||||
Color.Chrome = false;
|
||||
Color.Rubber = false;
|
||||
Color.Group = LC_COLORGROUP_SOLID;
|
||||
Color.Value[0] = FLT_MAX;
|
||||
Color.Value[1] = FLT_MAX;
|
||||
|
@ -157,8 +159,17 @@ static std::vector<lcColor> lcParseColorFile(lcFile& File)
|
|||
else if (Value != 0)
|
||||
Color.Group = LC_COLORGROUP_SPECIAL;
|
||||
}
|
||||
else if (!strcmp(Token, "CHROME") || !strcmp(Token, "PEARLESCENT") || !strcmp(Token, "RUBBER") ||
|
||||
!strcmp(Token, "MATTE_METALIC") || !strcmp(Token, "METAL") || !strcmp(Token, "LUMINANCE"))
|
||||
else if (!strcmp(Token, "CHROME"))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -236,6 +247,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
|||
|
||||
MainColor.Code = 16;
|
||||
MainColor.Translucent = false;
|
||||
MainColor.Chrome = false;
|
||||
MainColor.Rubber = false;
|
||||
MainColor.Group = LC_COLORGROUP_SOLID;
|
||||
MainColor.Value[0] = 1.0f;
|
||||
MainColor.Value[1] = 1.0f;
|
||||
|
@ -257,6 +270,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
|||
|
||||
EdgeColor.Code = 24;
|
||||
EdgeColor.Translucent = false;
|
||||
EdgeColor.Chrome = false;
|
||||
EdgeColor.Rubber = false;
|
||||
EdgeColor.Group = LC_NUM_COLORGROUPS;
|
||||
EdgeColor.Value[0] = 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.Translucent = false;
|
||||
StudCylinderColor.Chrome = false;
|
||||
StudCylinderColor.Rubber = false;
|
||||
StudCylinderColor.Group = LC_NUM_COLORGROUPS;
|
||||
StudCylinderColor.Value = lcVector4FromColor(Preferences.mStudCylinderColor);
|
||||
StudCylinderColor.Edge = lcVector4FromColor(Preferences.mPartEdgeColor);
|
||||
|
@ -294,6 +311,8 @@ bool lcLoadColorFile(lcFile& File, lcStudStyle StudStyle)
|
|||
|
||||
NoColor.Code = LC_COLOR_NOCOLOR;
|
||||
NoColor.Translucent = false;
|
||||
NoColor.Chrome = false;
|
||||
NoColor.Rubber = false;
|
||||
NoColor.Group = LC_NUM_COLORGROUPS;
|
||||
NoColor.Value[0] = 0.5f;
|
||||
NoColor.Value[1] = 0.5f;
|
||||
|
@ -362,6 +381,8 @@ int lcGetColorIndex(quint32 ColorCode)
|
|||
|
||||
Color.Code = ColorCode;
|
||||
Color.Translucent = false;
|
||||
Color.Chrome = false;
|
||||
Color.Rubber = false;
|
||||
Color.Edge[0] = 0.2f;
|
||||
Color.Edge[1] = 0.2f;
|
||||
Color.Edge[2] = 0.2f;
|
||||
|
|
|
@ -13,6 +13,8 @@ struct lcColor
|
|||
quint32 Code;
|
||||
int Group;
|
||||
bool Translucent = false;
|
||||
bool Chrome = false;
|
||||
bool Rubber = false;
|
||||
bool Adjusted = false;
|
||||
lcVector4 Value;
|
||||
lcVector4 Edge;
|
||||
|
@ -64,3 +66,13 @@ inline bool lcIsColorTranslucent(size_t ColorIndex)
|
|||
{
|
||||
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"),
|
||||
""
|
||||
},
|
||||
// LC_EDIT_TRANSFORM_RELATIVE
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformRelative"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Relative Transforms"),
|
||||
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_RELATIVE
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformRelative"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Relative Transforms"),
|
||||
QT_TRANSLATE_NOOP("Status", "Move and rotate 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
|
||||
// LC_EDIT_TRANSFORM_ABSOLUTE
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Edit.TransformToggleSeparate"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Toggle Separate Transforms"),
|
||||
QT_TRANSLATE_NOOP("Status", "Toggle rotating selected pieces separately"),
|
||||
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
|
||||
{
|
||||
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
|
||||
|
@ -641,18 +641,32 @@ const lcCommand gCommands[] =
|
|||
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("Menu", "Light"),
|
||||
QT_TRANSLATE_NOOP("Status", "Add new omni light sources to the model"),
|
||||
QT_TRANSLATE_NOOP("Action", "Edit.Tool.PointLight"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Point Light"),
|
||||
QT_TRANSLATE_NOOP("Status", "Add new point light sources to the model"),
|
||||
""
|
||||
},
|
||||
// LC_EDIT_ACTION_SPOTLIGHT
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Action", "Edit.Tool.Spotlight"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Spotlight"),
|
||||
QT_TRANSLATE_NOOP("Status", "Add new spotlights to the model"),
|
||||
QT_TRANSLATE_NOOP("Action", "Edit.Tool.SpotLight"),
|
||||
QT_TRANSLATE_NOOP("Menu", "Spot Light"),
|
||||
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
|
||||
|
@ -1362,7 +1376,7 @@ const lcCommand gCommands[] =
|
|||
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("Menu", "Open Selected Model"),
|
||||
|
@ -1858,21 +1872,23 @@ LC_ARRAY_SIZE_CHECK(gCommands, LC_NUM_COMMANDS);
|
|||
|
||||
const char* gToolNames[] =
|
||||
{
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewPiece"), // lcTool::Insert
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewPointLight"), // lcTool::Light
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewSpotLight"), // lcTool::SpotLight
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewCamera"), // lcTool::Camera
|
||||
QT_TRANSLATE_NOOP("Mouse", "Select"), // lcTool::Select
|
||||
QT_TRANSLATE_NOOP("Mouse", "Move"), // lcTool::Move
|
||||
QT_TRANSLATE_NOOP("Mouse", "Rotate"), // lcTool::Rotate
|
||||
QT_TRANSLATE_NOOP("Mouse", "Delete"), // lcTool::Eraser
|
||||
QT_TRANSLATE_NOOP("Mouse", "Paint"), // lcTool::Paint
|
||||
QT_TRANSLATE_NOOP("Mouse", "ColorPicker"), // lcTool::ColorPicker
|
||||
QT_TRANSLATE_NOOP("Mouse", "Zoom"), // lcTool::Zoom
|
||||
QT_TRANSLATE_NOOP("Mouse", "Pan"), // lcTool::Pan
|
||||
QT_TRANSLATE_NOOP("Mouse", "Orbit"), // lcTool::RotateView
|
||||
QT_TRANSLATE_NOOP("Mouse", "Roll"), // lcTool::Roll
|
||||
QT_TRANSLATE_NOOP("Mouse", "ZoomRegion") // lcTool::ZoomRegion
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewPiece"), // lcTool::Insert
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewPointLight"), // lcTool::PointLight
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewSpotLight"), // lcTool::SpotLight
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewDirectionalLight"), // lcTool::DirectionalLight
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewAreaLight"), // lcTool::AreaLight
|
||||
QT_TRANSLATE_NOOP("Mouse", "NewCamera"), // lcTool::Camera
|
||||
QT_TRANSLATE_NOOP("Mouse", "Select"), // lcTool::Select
|
||||
QT_TRANSLATE_NOOP("Mouse", "Move"), // lcTool::Move
|
||||
QT_TRANSLATE_NOOP("Mouse", "Rotate"), // lcTool::Rotate
|
||||
QT_TRANSLATE_NOOP("Mouse", "Delete"), // lcTool::Eraser
|
||||
QT_TRANSLATE_NOOP("Mouse", "Paint"), // lcTool::Paint
|
||||
QT_TRANSLATE_NOOP("Mouse", "ColorPicker"), // lcTool::ColorPicker
|
||||
QT_TRANSLATE_NOOP("Mouse", "Zoom"), // lcTool::Zoom
|
||||
QT_TRANSLATE_NOOP("Mouse", "Pan"), // lcTool::Pan
|
||||
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);
|
||||
|
|
|
@ -98,8 +98,10 @@ enum lcCommandId
|
|||
LC_EDIT_TRANSFORM_RELATIVE_ROTATION,
|
||||
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_DIRECTIONAL_LIGHT,
|
||||
LC_EDIT_ACTION_AREA_LIGHT,
|
||||
LC_EDIT_ACTION_CAMERA,
|
||||
LC_EDIT_ACTION_SELECT,
|
||||
LC_EDIT_ACTION_MOVE,
|
||||
|
@ -298,8 +300,10 @@ extern const lcCommand gCommands[];
|
|||
enum class lcTool
|
||||
{
|
||||
Insert,
|
||||
Light,
|
||||
PointLight,
|
||||
SpotLight,
|
||||
DirectionalLight,
|
||||
AreaLight,
|
||||
Camera,
|
||||
Select,
|
||||
Move,
|
||||
|
|
|
@ -75,6 +75,8 @@ class lcObject;
|
|||
class lcPiece;
|
||||
class lcCamera;
|
||||
class lcLight;
|
||||
enum class lcLightType;
|
||||
enum class lcLightAreaShape;
|
||||
class lcGroup;
|
||||
class PieceInfo;
|
||||
typedef std::map<const PieceInfo*, std::map<int, int>> lcPartsList;
|
||||
|
|
|
@ -204,13 +204,23 @@ void lcMainWindow::CreateActions()
|
|||
QIcon EditActionLightIcon;
|
||||
EditActionLightIcon.addFile(":/resources/action_light.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;
|
||||
EditActionSpotLightIcon.addFile(":/resources/action_spotlight.png");
|
||||
EditActionSpotLightIcon.addFile(":/resources/action_spotlight_16.png");
|
||||
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;
|
||||
EditActionSelectIcon.addFile(":/resources/action_select.png");
|
||||
EditActionSelectIcon.addFile(":/resources/action_select_16.png");
|
||||
|
@ -421,8 +431,10 @@ void lcMainWindow::CreateMenus()
|
|||
|
||||
mToolsMenu = new QMenu(tr("Tools"), this);
|
||||
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_DIRECTIONAL_LIGHT]);
|
||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_AREA_LIGHT]);
|
||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
|
||||
mToolsMenu->addSeparator();
|
||||
mToolsMenu->addAction(mActions[LC_EDIT_ACTION_SELECT]);
|
||||
|
@ -664,8 +676,10 @@ void lcMainWindow::CreateToolBars()
|
|||
mToolsToolBar->setObjectName("ToolsToolbar");
|
||||
insertToolBarBreak(mToolsToolBar);
|
||||
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_DIRECTIONAL_LIGHT]);
|
||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_AREA_LIGHT]);
|
||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_CAMERA]);
|
||||
mToolsToolBar->addSeparator();
|
||||
mToolsToolBar->addAction(mActions[LC_EDIT_ACTION_SELECT]);
|
||||
|
@ -817,7 +831,7 @@ void lcMainWindow::TogglePreviewWidget(bool Visible)
|
|||
else
|
||||
mPreviewToolBar->hide();
|
||||
}
|
||||
else if (Visible)
|
||||
else if (Visible)
|
||||
{
|
||||
CreatePreviewWidget();
|
||||
}
|
||||
|
@ -2887,62 +2901,62 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
|
|||
|
||||
case LC_PIECE_MOVE_PLUSX:
|
||||
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;
|
||||
|
||||
case LC_PIECE_MOVE_MINUSX:
|
||||
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;
|
||||
|
||||
case LC_PIECE_MOVE_PLUSY:
|
||||
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;
|
||||
|
||||
case LC_PIECE_MOVE_MINUSY:
|
||||
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;
|
||||
|
||||
case LC_PIECE_MOVE_PLUSZ:
|
||||
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;
|
||||
|
||||
case LC_PIECE_MOVE_MINUSZ:
|
||||
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;
|
||||
|
||||
case LC_PIECE_ROTATE_PLUSX:
|
||||
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;
|
||||
|
||||
case LC_PIECE_ROTATE_MINUSX:
|
||||
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;
|
||||
|
||||
case LC_PIECE_ROTATE_PLUSY:
|
||||
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;
|
||||
|
||||
case LC_PIECE_ROTATE_MINUSY:
|
||||
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;
|
||||
|
||||
case LC_PIECE_ROTATE_PLUSZ:
|
||||
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;
|
||||
|
||||
case LC_PIECE_ROTATE_MINUSZ:
|
||||
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;
|
||||
|
||||
case LC_PIECE_MINIFIG_WIZARD:
|
||||
|
@ -3362,8 +3376,16 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId)
|
|||
SetTool(lcTool::Insert);
|
||||
break;
|
||||
|
||||
case LC_EDIT_ACTION_LIGHT:
|
||||
SetTool(lcTool::Light);
|
||||
case LC_EDIT_ACTION_POINT_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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
class lcVector2i
|
||||
{
|
||||
public:
|
||||
lcVector2i()
|
||||
{
|
||||
}
|
||||
|
||||
constexpr lcVector2i(const int _x, const int _y)
|
||||
: x(_x), y(_y)
|
||||
{
|
||||
}
|
||||
|
||||
int x, y;
|
||||
};
|
||||
|
||||
class lcVector2
|
||||
{
|
||||
public:
|
||||
|
@ -649,6 +664,11 @@ inline lcVector3 lcVector3FromColor(quint32 Color)
|
|||
return v;
|
||||
}
|
||||
|
||||
inline lcVector3 lcVector3FromQColor(QColor Color)
|
||||
{
|
||||
return lcVector3(Color.redF(), Color.greenF(), Color.blueF());
|
||||
}
|
||||
|
||||
inline lcVector4 lcVector4FromColor(quint32 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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 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);
|
||||
File.WriteLine(Line);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
: mProject(Project), mIsPreview(Preview)
|
||||
{
|
||||
|
@ -540,7 +620,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
|||
|
||||
if (Token != QLatin1String("!LEOCAD"))
|
||||
{
|
||||
mFileLines.append(OriginalLine);
|
||||
mFileLines.append(OriginalLine);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -571,6 +651,19 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
|||
}
|
||||
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"))
|
||||
{
|
||||
|
@ -641,7 +734,7 @@ void lcModel::LoadLDraw(QIODevice& Device, Project* Project)
|
|||
|
||||
if (Library->IsPrimitive(CleanId.constData()))
|
||||
{
|
||||
mFileLines.append(OriginalLine);
|
||||
mFileLines.append(OriginalLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -946,7 +1039,7 @@ bool lcModel::LoadLDD(const QString& FileData)
|
|||
{
|
||||
std::vector<lcPiece*> Pieces;
|
||||
std::vector<std::vector<lcPiece*>> Groups;
|
||||
|
||||
|
||||
if (!lcImportLXFMLFile(FileData, Pieces, Groups))
|
||||
return false;
|
||||
|
||||
|
@ -2131,8 +2224,14 @@ lcMatrix33 lcModel::GetRelativeRotation() const
|
|||
{
|
||||
const lcObject* Focus = GetFocusObject();
|
||||
|
||||
if (Focus && Focus->IsPiece())
|
||||
return ((lcPiece*)Focus)->GetRelativeRotation();
|
||||
if (Focus)
|
||||
{
|
||||
if (Focus->IsPiece())
|
||||
return ((lcPiece*)Focus)->GetRelativeRotation();
|
||||
|
||||
if (Focus->IsLight())
|
||||
return ((lcLight*)Focus)->GetRelativeRotation();
|
||||
}
|
||||
}
|
||||
|
||||
return lcMatrix33Identity();
|
||||
|
@ -2606,7 +2705,7 @@ bool lcModel::RemoveSelectedObjects()
|
|||
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;
|
||||
lcMatrix33 RelativeRotation;
|
||||
|
@ -2667,7 +2766,7 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
|
|||
{
|
||||
if (Light->IsSelected())
|
||||
{
|
||||
Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance);
|
||||
Light->MoveSelected(mCurrentStep, gMainWindow->GetAddKeys(), TransformedObjectDistance, FirstMove);
|
||||
Light->UpdatePosition(mCurrentStep);
|
||||
Moved = true;
|
||||
}
|
||||
|
@ -2677,13 +2776,15 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector
|
|||
if (Moved && Update)
|
||||
{
|
||||
UpdateAllViews();
|
||||
|
||||
if (Checkpoint)
|
||||
SaveCheckpoint(tr("Moving"));
|
||||
|
||||
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)
|
||||
return;
|
||||
|
@ -2712,6 +2813,12 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
|
|||
}
|
||||
else
|
||||
{
|
||||
int Flags;
|
||||
lcArray<lcObject*> Selection;
|
||||
lcObject* Focus;
|
||||
|
||||
GetSelectionInformation(&Flags, Selection, &Focus);
|
||||
|
||||
if (!gMainWindow->GetSeparateTransform())
|
||||
{
|
||||
lcVector3 Center;
|
||||
|
@ -2729,42 +2836,78 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
|
|||
else
|
||||
WorldToFocusMatrix = lcMatrix33Identity();
|
||||
|
||||
for (lcPiece* Piece : mPieces)
|
||||
for (lcObject* Object : Selection)
|
||||
{
|
||||
if (!Piece->IsSelected())
|
||||
continue;
|
||||
if (Object->IsPiece())
|
||||
{
|
||||
lcPiece* Piece = (lcPiece*)Object;
|
||||
|
||||
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
||||
Piece->UpdatePosition(mCurrentStep);
|
||||
Rotated = true;
|
||||
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
||||
Piece->UpdatePosition(mCurrentStep);
|
||||
Rotated = true;
|
||||
}
|
||||
else if (Object->IsLight())
|
||||
{
|
||||
lcLight* Light = (lcLight*)Object;
|
||||
|
||||
Light->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix);
|
||||
Light->UpdatePosition(mCurrentStep);
|
||||
Rotated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (lcPiece* Piece : mPieces)
|
||||
for (lcObject* Object : Selection)
|
||||
{
|
||||
if (!Piece->IsSelected())
|
||||
continue;
|
||||
|
||||
const lcVector3 Center = Piece->GetRotationCenter();
|
||||
lcMatrix33 WorldToFocusMatrix;
|
||||
lcMatrix33 RelativeRotationMatrix;
|
||||
|
||||
if (Relative)
|
||||
if (Object->IsPiece())
|
||||
{
|
||||
const lcMatrix33 RelativeRotation = Piece->GetRelativeRotation();
|
||||
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
|
||||
RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldToFocusMatrix = lcMatrix33Identity();
|
||||
RelativeRotationMatrix = RotationMatrix;
|
||||
}
|
||||
lcPiece* Piece = (lcPiece*)Object;
|
||||
|
||||
Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix);
|
||||
Piece->UpdatePosition(mCurrentStep);
|
||||
Rotated = true;
|
||||
const lcVector3 Center = Piece->GetRotationCenter();
|
||||
lcMatrix33 WorldToFocusMatrix;
|
||||
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)
|
||||
{
|
||||
case lcTransformType::AbsoluteTranslation:
|
||||
MoveSelectedObjects(Transform, false, false, true, true);
|
||||
MoveSelectedObjects(Transform, false, false, true, true, true);
|
||||
break;
|
||||
|
||||
case lcTransformType::RelativeTranslation:
|
||||
MoveSelectedObjects(Transform, true, false, true, true);
|
||||
MoveSelectedObjects(Transform, true, false, true, true, true);
|
||||
break;
|
||||
|
||||
case lcTransformType::AbsoluteRotation:
|
||||
RotateSelectedPieces(Transform, false, false, true, true);
|
||||
RotateSelectedObjects(Transform, false, false, true, true);
|
||||
break;
|
||||
|
||||
case lcTransformType::RelativeRotation:
|
||||
RotateSelectedPieces(Transform, true, false, true, true);
|
||||
RotateSelectedObjects(Transform, true, false, true, true);
|
||||
break;
|
||||
|
||||
case lcTransformType::Count:
|
||||
|
@ -3011,6 +3154,147 @@ void lcModel::SetCameraName(lcCamera* Camera, const QString& Name)
|
|||
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
|
||||
{
|
||||
for (const lcPiece* Piece : mPieces)
|
||||
|
@ -3123,20 +3407,18 @@ bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRota
|
|||
if (!Light->IsSelected())
|
||||
continue;
|
||||
|
||||
if (Light->IsFocused() && Relative)
|
||||
if (Light->IsFocused())
|
||||
{
|
||||
Center = Light->GetSectionPosition(Light->GetFocusSection());
|
||||
// RelativeRotation = Piece->GetRelativeRotation();
|
||||
Center = Light->GetRotationCenter();
|
||||
|
||||
if (Relative)
|
||||
RelativeRotation = Light->GetRelativeRotation();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION);
|
||||
NumSelected++;
|
||||
if (Light->IsSpotLight() || Light->IsDirectionalLight())
|
||||
{
|
||||
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_TARGET);
|
||||
NumSelected++;
|
||||
}
|
||||
}
|
||||
|
||||
if (NumSelected)
|
||||
|
@ -3148,6 +3430,33 @@ bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRota
|
|||
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
|
||||
{
|
||||
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())
|
||||
{
|
||||
Selection.Add(Camera);
|
||||
*Flags |= LC_SEL_SELECTED;
|
||||
*Flags |= LC_SEL_SELECTED | LC_SEL_CAMERA;
|
||||
|
||||
if (Camera->IsFocused())
|
||||
*Focus = Camera;
|
||||
|
@ -3434,7 +3743,7 @@ void lcModel::GetSelectionInformation(int* Flags, lcArray<lcObject*>& Selection,
|
|||
if (Light->IsSelected())
|
||||
{
|
||||
Selection.Add(Light);
|
||||
*Flags |= LC_SEL_SELECTED;
|
||||
*Flags |= LC_SEL_SELECTED | LC_SEL_LIGHT;
|
||||
|
||||
if (Light->IsFocused())
|
||||
*Focus = Light;
|
||||
|
@ -3940,6 +4249,7 @@ void lcModel::RedoAction()
|
|||
void lcModel::BeginMouseTool()
|
||||
{
|
||||
mMouseToolDistance = lcVector3(0.0f, 0.0f, 0.0f);
|
||||
mMouseToolFirstMove = true;
|
||||
}
|
||||
|
||||
void lcModel::EndMouseTool(lcTool Tool, bool Accept)
|
||||
|
@ -3954,11 +4264,10 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept)
|
|||
switch (Tool)
|
||||
{
|
||||
case lcTool::Insert:
|
||||
case lcTool::Light:
|
||||
break;
|
||||
|
||||
case lcTool::PointLight:
|
||||
case lcTool::SpotLight:
|
||||
SaveCheckpoint(tr("New SpotLight"));
|
||||
case lcTool::DirectionalLight:
|
||||
case lcTool::AreaLight:
|
||||
break;
|
||||
|
||||
case lcTool::Camera:
|
||||
|
@ -4024,37 +4333,35 @@ void lcModel::InsertPieceToolClicked(const lcMatrix44& WorldMatrix)
|
|||
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);
|
||||
mLights.Add(Light);
|
||||
|
||||
ClearSelectionAndSetFocus(Light, LC_LIGHT_SECTION_POSITION, false);
|
||||
SaveCheckpoint(tr("New Light"));
|
||||
}
|
||||
|
||||
void lcModel::BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target)
|
||||
{
|
||||
lcLight* Light = new lcLight(Position[0], Position[1], Position[2], Target[0], Target[1], Target[2]);
|
||||
mLights.Add(Light);
|
||||
switch (LightType)
|
||||
{
|
||||
case lcLightType::Point:
|
||||
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)
|
||||
{
|
||||
lcLight* Light = mLights[mLights.GetSize() - 1];
|
||||
case lcLightType::Area:
|
||||
SaveCheckpoint(tr("New Area Light"));
|
||||
break;
|
||||
|
||||
Light->MoveSelected(1, false, Position - mMouseToolDistance);
|
||||
Light->UpdatePosition(1);
|
||||
|
||||
mMouseToolDistance = Position;
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(false);
|
||||
UpdateAllViews();
|
||||
case lcLightType::Count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
mMouseToolDistance = Position;
|
||||
mMouseToolFirstMove = false;
|
||||
|
||||
ClearSelectionAndSetFocus(Camera, LC_CAMERA_SECTION_TARGET, false);
|
||||
}
|
||||
|
@ -4076,6 +4384,7 @@ void lcModel::UpdateCameraTool(const lcVector3& Position)
|
|||
Camera->UpdatePosition(1);
|
||||
|
||||
mMouseToolDistance = Position;
|
||||
mMouseToolFirstMove = false;
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(false);
|
||||
UpdateAllViews();
|
||||
|
@ -4086,8 +4395,10 @@ void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool
|
|||
const lcVector3 PieceDistance = SnapPosition(Distance) - SnapPosition(mMouseToolDistance);
|
||||
const lcVector3 ObjectDistance = Distance - mMouseToolDistance;
|
||||
|
||||
MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false);
|
||||
MoveSelectedObjects(PieceDistance, ObjectDistance, AllowRelative, AlternateButtonDrag, true, false, mMouseToolFirstMove);
|
||||
|
||||
mMouseToolDistance = Distance;
|
||||
mMouseToolFirstMove = false;
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(false);
|
||||
UpdateAllViews();
|
||||
|
@ -4096,8 +4407,10 @@ void lcModel::UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool
|
|||
void lcModel::UpdateRotateTool(const lcVector3& Angles, bool AlternateButtonDrag)
|
||||
{
|
||||
const lcVector3 Delta = SnapRotation(Angles) - SnapRotation(mMouseToolDistance);
|
||||
RotateSelectedPieces(Delta, true, AlternateButtonDrag, false, false);
|
||||
RotateSelectedObjects(Delta, true, AlternateButtonDrag, false, false);
|
||||
|
||||
mMouseToolDistance = Angles;
|
||||
mMouseToolFirstMove = false;
|
||||
|
||||
gMainWindow->UpdateSelectedObjects(false);
|
||||
UpdateAllViews();
|
||||
|
@ -4347,7 +4660,7 @@ void lcModel::ShowArrayDialog()
|
|||
QMessageBox::information(gMainWindow, tr("LeoCAD"), tr("No pieces selected."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
lcArrayDialog Dialog(gMainWindow);
|
||||
|
||||
if (Dialog.exec() != QDialog::Accepted)
|
||||
|
|
|
@ -5,18 +5,20 @@
|
|||
#include "lc_array.h"
|
||||
|
||||
#define LC_SEL_NO_PIECES 0x0001 // No pieces in model
|
||||
#define LC_SEL_PIECE 0x0002 // At last 1 piece selected
|
||||
#define LC_SEL_SELECTED 0x0004 // At last 1 object selected
|
||||
#define LC_SEL_UNSELECTED 0x0008 // At least 1 piece unselected
|
||||
#define LC_SEL_HIDDEN 0x0010 // At least one piece hidden
|
||||
#define LC_SEL_HIDDEN_SELECTED 0x0020 // At least one piece selected is hidden
|
||||
#define LC_SEL_VISIBLE_SELECTED 0x0040 // At least one piece selected is not hidden
|
||||
#define LC_SEL_GROUPED 0x0080 // At least one piece selected is grouped
|
||||
#define LC_SEL_FOCUS_GROUPED 0x0100 // Focused piece is grouped
|
||||
#define LC_SEL_CAN_GROUP 0x0200 // Can make a new group
|
||||
#define LC_SEL_MODEL_SELECTED 0x0400 // At least one model reference is selected
|
||||
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x0800 // Can add control points to focused piece
|
||||
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x1000 // Can remove control points from focused piece
|
||||
#define LC_SEL_PIECE 0x0002 // At least 1 piece selected
|
||||
#define LC_SEL_CAMERA 0x0004 // At least 1 camera selected
|
||||
#define LC_SEL_LIGHT 0x0008 // At least 1 light selected
|
||||
#define LC_SEL_SELECTED 0x0010 // At least 1 object selected
|
||||
#define LC_SEL_UNSELECTED 0x0020 // At least 1 piece unselected
|
||||
#define LC_SEL_HIDDEN 0x0040 // At least one piece hidden
|
||||
#define LC_SEL_HIDDEN_SELECTED 0x0080 // At least one piece selected is hidden
|
||||
#define LC_SEL_VISIBLE_SELECTED 0x0100 // At least one piece selected is not hidden
|
||||
#define LC_SEL_GROUPED 0x0200 // At least one piece selected is grouped
|
||||
#define LC_SEL_FOCUS_GROUPED 0x0400 // Focused piece is grouped
|
||||
#define LC_SEL_CAN_GROUP 0x0800 // Can make a new group
|
||||
#define LC_SEL_MODEL_SELECTED 0x1000 // At least one model reference is selected
|
||||
#define LC_SEL_CAN_ADD_CONTROL_POINT 0x2000 // Can add control points to focused piece
|
||||
#define LC_SEL_CAN_REMOVE_CONTROL_POINT 0x4000 // Can remove control points from focused piece
|
||||
|
||||
enum class lcSelectionMode
|
||||
{
|
||||
|
@ -67,6 +69,26 @@ public:
|
|||
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
|
||||
{
|
||||
QByteArray File;
|
||||
|
@ -136,6 +158,11 @@ public:
|
|||
return mProperties;
|
||||
}
|
||||
|
||||
const lcPOVRayOptions& GetPOVRayOptions() const
|
||||
{
|
||||
return mPOVRayOptions;
|
||||
}
|
||||
|
||||
void SetFileName(const QString& FileName)
|
||||
{
|
||||
if (mProperties.mModelName == mProperties.mFileName)
|
||||
|
@ -254,6 +281,7 @@ public:
|
|||
lcModel* GetFirstSelectedSubmodel() const;
|
||||
void GetSubModels(lcArray<lcModel*>& SubModels) const;
|
||||
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
|
||||
bool CanRotateSelection() const;
|
||||
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
|
||||
lcVector3 GetSelectionOrModelCenter() const;
|
||||
bool GetFocusPosition(lcVector3& Position) const;
|
||||
|
@ -301,9 +329,7 @@ public:
|
|||
void BeginMouseTool();
|
||||
void EndMouseTool(lcTool Tool, bool Accept);
|
||||
void InsertPieceToolClicked(const lcMatrix44& WorldMatrix);
|
||||
void PointLightToolClicked(const lcVector3& Position);
|
||||
void BeginSpotLightTool(const lcVector3& Position, const lcVector3& Target);
|
||||
void UpdateSpotLightTool(const lcVector3& Position);
|
||||
void InsertLightToolClicked(const lcVector3& Position, lcLightType LightType);
|
||||
void BeginCameraTool(const lcVector3& Position, const lcVector3& Target);
|
||||
void UpdateCameraTool(const lcVector3& Position);
|
||||
void UpdateMoveTool(const lcVector3& Distance, bool AllowRelative, bool AlternateButtonDrag);
|
||||
|
@ -322,13 +348,13 @@ public:
|
|||
void ZoomExtents(lcCamera* Camera, float Aspect);
|
||||
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 RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint);
|
||||
void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool AllowRelative, bool AlternateButtonDrag, bool Update, bool Checkpoint, bool FirstMove);
|
||||
void RotateSelectedObjects(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint);
|
||||
void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint);
|
||||
void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform);
|
||||
void SetSelectedPiecesColorIndex(int ColorIndex);
|
||||
|
@ -342,6 +368,20 @@ public:
|
|||
void SetCameraZFar(lcCamera* Camera, float ZFar);
|
||||
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 ShowSelectByNameDialog();
|
||||
void ShowArrayDialog();
|
||||
|
@ -363,6 +403,7 @@ protected:
|
|||
void AddPiece(lcPiece* Piece);
|
||||
void InsertPiece(lcPiece* Piece, int Index);
|
||||
|
||||
lcPOVRayOptions mPOVRayOptions;
|
||||
lcModelProperties mProperties;
|
||||
Project* const mProject;
|
||||
PieceInfo* mPieceInfo;
|
||||
|
@ -371,6 +412,7 @@ protected:
|
|||
bool mActive;
|
||||
lcStep mCurrentStep;
|
||||
lcVector3 mMouseToolDistance;
|
||||
bool mMouseToolFirstMove;
|
||||
|
||||
lcArray<lcPiece*> mPieces;
|
||||
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", "Version", ""), // LC_PROFILE_BLENDER_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("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_VERSION,
|
||||
LC_PROFILE_BLENDER_ADDON_VERSION,
|
||||
LC_PROFILE_BLENDER_ADDON_VERSION_CHECK,
|
||||
LC_PROFILE_BLENDER_IMPORT_MODULE,
|
||||
|
||||
LC_PROFILE_PREVIEW_VIEW_SPHERE_ENABLED,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "lc_viewwidget.h"
|
||||
#include <stdlib.h>
|
||||
#include "lc_mainwindow.h"
|
||||
#include "light.h"
|
||||
#include "camera.h"
|
||||
#include "texfont.h"
|
||||
#include "lc_texture.h"
|
||||
|
@ -415,7 +416,7 @@ lcMatrix44 lcView::GetPieceInsertPosition(bool IgnoreSelected, PieceInfo* Info)
|
|||
lcModel* ActiveModel = GetActiveModel();
|
||||
|
||||
lcPieceInfoRayTest PieceInfoRayTest = FindPieceInfoUnderPointer(IgnoreSelected);
|
||||
|
||||
|
||||
if (PieceInfoRayTest.Info)
|
||||
{
|
||||
lcVector3 Position = PieceInfoRayTest.Plane;
|
||||
|
@ -927,7 +928,7 @@ void lcView::OnDraw()
|
|||
mViewManipulator->DrawSelectMove(mTrackButton, mTrackTool);
|
||||
else if (GetCurrentTool() == lcTool::Move && mTrackButton != lcTrackButton::None)
|
||||
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);
|
||||
else if ((mTrackTool == lcTrackTool::Select || mTrackTool == lcTrackTool::ZoomRegion) && mTrackButton != lcTrackButton::None)
|
||||
DrawSelectZoomRegionOverlay();
|
||||
|
@ -1361,7 +1362,7 @@ void lcView::DrawRotateViewOverlay()
|
|||
mContext->SetVertexBufferPointer(Verts);
|
||||
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,
|
||||
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[] =
|
||||
{
|
||||
lcTrackTool::Insert, // lcTool::Insert
|
||||
lcTrackTool::PointLight, // lcTool::Light
|
||||
lcTrackTool::SpotLight, // lcTool::SpotLight
|
||||
lcTrackTool::Camera, // lcTool::Camera
|
||||
lcTrackTool::Select, // lcTool::Select
|
||||
lcTrackTool::MoveXYZ, // lcTool::Move
|
||||
lcTrackTool::RotateXYZ, // lcTool::Rotate
|
||||
lcTrackTool::Eraser, // lcTool::Eraser
|
||||
lcTrackTool::Paint, // lcTool::Paint
|
||||
lcTrackTool::ColorPicker, // lcTool::ColorPicker
|
||||
lcTrackTool::Zoom, // lcTool::Zoom
|
||||
lcTrackTool::Pan, // lcTool::Pan
|
||||
lcTrackTool::OrbitXY, // lcTool::RotateView
|
||||
lcTrackTool::Roll, // lcTool::Roll
|
||||
lcTrackTool::ZoomRegion // lcTool::ZoomRegion
|
||||
lcTrackTool::Insert, // lcTool::Insert
|
||||
lcTrackTool::PointLight, // lcTool::PointLight
|
||||
lcTrackTool::SpotLight, // lcTool::SpotLight
|
||||
lcTrackTool::DirectionalLight, // lcTool::DirectionalLight
|
||||
lcTrackTool::AreaLight, // lcTool::AreaLight
|
||||
lcTrackTool::Camera, // lcTool::Camera
|
||||
lcTrackTool::Select, // lcTool::Select
|
||||
lcTrackTool::MoveXYZ, // lcTool::Move
|
||||
lcTrackTool::RotateXYZ, // lcTool::Rotate
|
||||
lcTrackTool::Eraser, // lcTool::Eraser
|
||||
lcTrackTool::Paint, // lcTool::Paint
|
||||
lcTrackTool::ColorPicker, // lcTool::ColorPicker
|
||||
lcTrackTool::Zoom, // lcTool::Zoom
|
||||
lcTrackTool::Pan, // lcTool::Pan
|
||||
lcTrackTool::OrbitXY, // lcTool::RotateView
|
||||
lcTrackTool::Roll, // lcTool::Roll
|
||||
lcTrackTool::ZoomRegion // lcTool::ZoomRegion
|
||||
};
|
||||
|
||||
LC_ARRAY_SIZE_CHECK(TrackToolFromTool, lcTool::Count);
|
||||
|
@ -1864,36 +1867,38 @@ lcCursor lcView::GetCursor() const
|
|||
|
||||
constexpr lcCursor CursorFromTrackTool[] =
|
||||
{
|
||||
lcCursor::Select, // lcTrackTool::None
|
||||
lcCursor::Brick, // lcTrackTool::Insert
|
||||
lcCursor::Light, // lcTrackTool::PointLight
|
||||
lcCursor::Spotlight, // lcTrackTool::SpotLight
|
||||
lcCursor::Camera, // lcTrackTool::Camera
|
||||
lcCursor::Select, // lcTrackTool::Select
|
||||
lcCursor::Move, // lcTrackTool::MoveX
|
||||
lcCursor::Move, // lcTrackTool::MoveY
|
||||
lcCursor::Move, // lcTrackTool::MoveZ
|
||||
lcCursor::Move, // lcTrackTool::MoveXY
|
||||
lcCursor::Move, // lcTrackTool::MoveXZ
|
||||
lcCursor::Move, // lcTrackTool::MoveYZ
|
||||
lcCursor::Move, // lcTrackTool::MoveXYZ
|
||||
lcCursor::Rotate, // lcTrackTool::RotateX
|
||||
lcCursor::Rotate, // lcTrackTool::RotateY
|
||||
lcCursor::Rotate, // lcTrackTool::RotateZ
|
||||
lcCursor::Rotate, // lcTrackTool::RotateXY
|
||||
lcCursor::Rotate, // lcTrackTool::RotateXYZ
|
||||
lcCursor::Move, // lcTrackTool::ScalePlus
|
||||
lcCursor::Move, // lcTrackTool::ScaleMinus
|
||||
lcCursor::Delete, // lcTrackTool::Eraser
|
||||
lcCursor::Paint, // lcTrackTool::Paint
|
||||
lcCursor::ColorPicker, // lcTrackTool::ColorPicker
|
||||
lcCursor::Zoom, // lcTrackTool::Zoom
|
||||
lcCursor::Pan, // lcTrackTool::Pan
|
||||
lcCursor::RotateX, // lcTrackTool::OrbitX
|
||||
lcCursor::RotateY, // lcTrackTool::OrbitY
|
||||
lcCursor::RotateView, // lcTrackTool::OrbitXY
|
||||
lcCursor::Roll, // lcTrackTool::Roll
|
||||
lcCursor::ZoomRegion // lcTrackTool::ZoomRegion
|
||||
lcCursor::Select, // lcTrackTool::None
|
||||
lcCursor::Brick, // lcTrackTool::Insert
|
||||
lcCursor::PointLight, // lcTrackTool::PointLight
|
||||
lcCursor::SpotLight, // lcTrackTool::SpotLight
|
||||
lcCursor::DirectionalLight, // lcTrackTool::DirectionalLight
|
||||
lcCursor::AreaLight, // lcTrackTool::AreaLight
|
||||
lcCursor::Camera, // lcTrackTool::Camera
|
||||
lcCursor::Select, // lcTrackTool::Select
|
||||
lcCursor::Move, // lcTrackTool::MoveX
|
||||
lcCursor::Move, // lcTrackTool::MoveY
|
||||
lcCursor::Move, // lcTrackTool::MoveZ
|
||||
lcCursor::Move, // lcTrackTool::MoveXY
|
||||
lcCursor::Move, // lcTrackTool::MoveXZ
|
||||
lcCursor::Move, // lcTrackTool::MoveYZ
|
||||
lcCursor::Move, // lcTrackTool::MoveXYZ
|
||||
lcCursor::Rotate, // lcTrackTool::RotateX
|
||||
lcCursor::Rotate, // lcTrackTool::RotateY
|
||||
lcCursor::Rotate, // lcTrackTool::RotateZ
|
||||
lcCursor::Rotate, // lcTrackTool::RotateXY
|
||||
lcCursor::Rotate, // lcTrackTool::RotateXYZ
|
||||
lcCursor::Move, // lcTrackTool::ScalePlus
|
||||
lcCursor::Move, // lcTrackTool::ScaleMinus
|
||||
lcCursor::Delete, // lcTrackTool::Eraser
|
||||
lcCursor::Paint, // lcTrackTool::Paint
|
||||
lcCursor::ColorPicker, // lcTrackTool::ColorPicker
|
||||
lcCursor::Zoom, // lcTrackTool::Zoom
|
||||
lcCursor::Pan, // lcTrackTool::Pan
|
||||
lcCursor::RotateX, // lcTrackTool::OrbitX
|
||||
lcCursor::RotateY, // lcTrackTool::OrbitY
|
||||
lcCursor::RotateView, // lcTrackTool::OrbitXY
|
||||
lcCursor::Roll, // lcTrackTool::Roll
|
||||
lcCursor::ZoomRegion // lcTrackTool::ZoomRegion
|
||||
};
|
||||
|
||||
LC_ARRAY_SIZE_CHECK(CursorFromTrackTool, lcTrackTool::Count);
|
||||
|
@ -1920,8 +1925,10 @@ void lcView::SetCursor(lcCursor CursorType)
|
|||
{ 0, 0, "" }, // lcCursor::Hidden
|
||||
{ 0, 0, "" }, // lcCursor::Default
|
||||
{ 8, 3, ":/resources/cursor_insert" }, // lcCursor::Brick
|
||||
{ 15, 15, ":/resources/cursor_light" }, // lcCursor::Light
|
||||
{ 7, 10, ":/resources/cursor_spotlight" }, // lcCursor::Spotlight
|
||||
{ 15, 15, ":/resources/cursor_light" }, // lcCursor::PointLight
|
||||
{ 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
|
||||
{ 0, 2, ":/resources/cursor_select" }, // lcCursor::Select
|
||||
{ 0, 2, ":/resources/cursor_select_add" }, // lcCursor::SelectAdd
|
||||
|
@ -1969,36 +1976,38 @@ lcTool lcView::GetCurrentTool() const
|
|||
{
|
||||
constexpr lcTool ToolFromTrackTool[] =
|
||||
{
|
||||
lcTool::Select, // lcTrackTool::None
|
||||
lcTool::Insert, // lcTrackTool::Insert
|
||||
lcTool::Light, // lcTrackTool::PointLight
|
||||
lcTool::SpotLight, // lcTrackTool::SpotLight
|
||||
lcTool::Camera, // lcTrackTool::Camera
|
||||
lcTool::Select, // lcTrackTool::Select
|
||||
lcTool::Move, // lcTrackTool::MoveX
|
||||
lcTool::Move, // lcTrackTool::MoveY
|
||||
lcTool::Move, // lcTrackTool::MoveZ
|
||||
lcTool::Move, // lcTrackTool::MoveXY
|
||||
lcTool::Move, // lcTrackTool::MoveXZ
|
||||
lcTool::Move, // lcTrackTool::MoveYZ
|
||||
lcTool::Move, // lcTrackTool::MoveXYZ
|
||||
lcTool::Rotate, // lcTrackTool::RotateX
|
||||
lcTool::Rotate, // lcTrackTool::RotateY
|
||||
lcTool::Rotate, // lcTrackTool::RotateZ
|
||||
lcTool::Rotate, // lcTrackTool::RotateXY
|
||||
lcTool::Rotate, // lcTrackTool::RotateXYZ
|
||||
lcTool::Move, // lcTrackTool::ScalePlus
|
||||
lcTool::Move, // lcTrackTool::ScaleMinus
|
||||
lcTool::Eraser, // lcTrackTool::Eraser
|
||||
lcTool::Paint, // lcTrackTool::Paint
|
||||
lcTool::ColorPicker, // lcTrackTool::ColorPicker
|
||||
lcTool::Zoom, // lcTrackTool::Zoom
|
||||
lcTool::Pan, // lcTrackTool::Pan
|
||||
lcTool::RotateView, // lcTrackTool::OrbitX
|
||||
lcTool::RotateView, // lcTrackTool::OrbitY
|
||||
lcTool::RotateView, // lcTrackTool::OrbitXY
|
||||
lcTool::Roll, // lcTrackTool::Roll
|
||||
lcTool::ZoomRegion // lcTrackTool::ZoomRegion
|
||||
lcTool::Select, // lcTrackTool::None
|
||||
lcTool::Insert, // lcTrackTool::Insert
|
||||
lcTool::PointLight, // lcTrackTool::PointLight
|
||||
lcTool::SpotLight, // lcTrackTool::SpotLight
|
||||
lcTool::DirectionalLight, // lcTrackTool::DirectionalLight
|
||||
lcTool::AreaLight, // lcTrackTool::AreaLight
|
||||
lcTool::Camera, // lcTrackTool::Camera
|
||||
lcTool::Select, // lcTrackTool::Select
|
||||
lcTool::Move, // lcTrackTool::MoveX
|
||||
lcTool::Move, // lcTrackTool::MoveY
|
||||
lcTool::Move, // lcTrackTool::MoveZ
|
||||
lcTool::Move, // lcTrackTool::MoveXY
|
||||
lcTool::Move, // lcTrackTool::MoveXZ
|
||||
lcTool::Move, // lcTrackTool::MoveYZ
|
||||
lcTool::Move, // lcTrackTool::MoveXYZ
|
||||
lcTool::Rotate, // lcTrackTool::RotateX
|
||||
lcTool::Rotate, // lcTrackTool::RotateY
|
||||
lcTool::Rotate, // lcTrackTool::RotateZ
|
||||
lcTool::Rotate, // lcTrackTool::RotateXY
|
||||
lcTool::Rotate, // lcTrackTool::RotateXYZ
|
||||
lcTool::Move, // lcTrackTool::ScalePlus
|
||||
lcTool::Move, // lcTrackTool::ScaleMinus
|
||||
lcTool::Eraser, // lcTrackTool::Eraser
|
||||
lcTool::Paint, // lcTrackTool::Paint
|
||||
lcTool::ColorPicker, // lcTrackTool::ColorPicker
|
||||
lcTool::Zoom, // lcTrackTool::Zoom
|
||||
lcTool::Pan, // lcTrackTool::Pan
|
||||
lcTool::RotateView, // lcTrackTool::OrbitX
|
||||
lcTool::RotateView, // lcTrackTool::OrbitY
|
||||
lcTool::RotateView, // lcTrackTool::OrbitXY
|
||||
lcTool::Roll, // lcTrackTool::Roll
|
||||
lcTool::ZoomRegion // lcTrackTool::ZoomRegion
|
||||
};
|
||||
|
||||
LC_ARRAY_SIZE_CHECK(ToolFromTrackTool, lcTrackTool::Count);
|
||||
|
@ -2032,7 +2041,7 @@ void lcView::UpdateTrackTool()
|
|||
NewTrackTool = lcTrackTool::Insert;
|
||||
break;
|
||||
|
||||
case lcTool::Light:
|
||||
case lcTool::PointLight:
|
||||
NewTrackTool = lcTrackTool::PointLight;
|
||||
break;
|
||||
|
||||
|
@ -2040,6 +2049,14 @@ void lcView::UpdateTrackTool()
|
|||
NewTrackTool = lcTrackTool::SpotLight;
|
||||
break;
|
||||
|
||||
case lcTool::DirectionalLight:
|
||||
NewTrackTool = lcTrackTool::DirectionalLight;
|
||||
break;
|
||||
|
||||
case lcTool::AreaLight:
|
||||
NewTrackTool = lcTrackTool::AreaLight;
|
||||
break;
|
||||
|
||||
case lcTool::Camera:
|
||||
NewTrackTool = lcTrackTool::Camera;
|
||||
break;
|
||||
|
@ -2258,16 +2275,11 @@ void lcView::StartTracking(lcTrackButton TrackButton)
|
|||
switch (Tool)
|
||||
{
|
||||
case lcTool::Insert:
|
||||
case lcTool::Light:
|
||||
break;
|
||||
|
||||
case lcTool::PointLight:
|
||||
case lcTool::SpotLight:
|
||||
{
|
||||
lcVector3 Position = GetCameraLightInsertPosition();
|
||||
lcVector3 Target = Position + lcVector3(0.1f, 0.1f, 0.1f);
|
||||
ActiveModel->BeginSpotLightTool(Position, Target);
|
||||
}
|
||||
break;
|
||||
case lcTool::DirectionalLight:
|
||||
case lcTool::AreaLight:
|
||||
break;
|
||||
|
||||
case lcTool::Camera:
|
||||
{
|
||||
|
@ -2322,10 +2334,12 @@ void lcView::StopTracking(bool Accept)
|
|||
switch (Tool)
|
||||
{
|
||||
case lcTool::Insert:
|
||||
case lcTool::Light:
|
||||
case lcTool::PointLight:
|
||||
break;
|
||||
|
||||
case lcTool::SpotLight:
|
||||
case lcTool::DirectionalLight:
|
||||
case lcTool::AreaLight:
|
||||
case lcTool::Camera:
|
||||
ActiveModel->EndMouseTool(Tool, Accept);
|
||||
break;
|
||||
|
@ -2418,6 +2432,17 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
|
|||
lcModel* ActiveModel = GetActiveModel();
|
||||
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)
|
||||
{
|
||||
case lcTrackTool::None:
|
||||
|
@ -2441,22 +2466,25 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
|
|||
break;
|
||||
|
||||
case lcTrackTool::PointLight:
|
||||
{
|
||||
ActiveModel->PointLightToolClicked(GetCameraLightInsertPosition());
|
||||
|
||||
if ((mMouseModifiers & Qt::ControlModifier) == 0)
|
||||
gMainWindow->SetTool(lcTool::Select);
|
||||
|
||||
mToolClicked = true;
|
||||
UpdateTrackTool();
|
||||
}
|
||||
AddLight(lcLightType::Point);
|
||||
break;
|
||||
|
||||
case lcTrackTool::SpotLight:
|
||||
AddLight(lcLightType::Spot);
|
||||
break;
|
||||
|
||||
case lcTrackTool::DirectionalLight:
|
||||
AddLight(lcLightType::Directional);
|
||||
break;
|
||||
|
||||
case lcTrackTool::AreaLight:
|
||||
AddLight(lcLightType::Area);
|
||||
break;
|
||||
|
||||
case lcTrackTool::Camera:
|
||||
StartTracking(TrackButton);
|
||||
break;
|
||||
|
||||
|
||||
case lcTrackTool::Select:
|
||||
{
|
||||
lcObjectSection ObjectSection = FindObjectUnderPointer(false, false);
|
||||
|
@ -2488,7 +2516,7 @@ void lcView::OnButtonDown(lcTrackButton TrackButton)
|
|||
case lcTrackTool::RotateZ:
|
||||
case lcTrackTool::RotateXY:
|
||||
case lcTrackTool::RotateXYZ:
|
||||
if (ActiveModel->AnyPiecesSelected())
|
||||
if (ActiveModel->CanRotateSelection())
|
||||
StartTracking(TrackButton);
|
||||
break;
|
||||
|
||||
|
@ -2687,10 +2715,9 @@ void lcView::OnMouseMove()
|
|||
case lcTrackTool::None:
|
||||
case lcTrackTool::Insert:
|
||||
case lcTrackTool::PointLight:
|
||||
break;
|
||||
|
||||
case lcTrackTool::SpotLight:
|
||||
ActiveModel->UpdateSpotLightTool(GetCameraLightInsertPosition());
|
||||
case lcTrackTool::DirectionalLight:
|
||||
case lcTrackTool::AreaLight:
|
||||
break;
|
||||
|
||||
case lcTrackTool::Camera:
|
||||
|
|
|
@ -17,8 +17,10 @@ enum class lcCursor
|
|||
Hidden = First,
|
||||
Default,
|
||||
Brick,
|
||||
Light,
|
||||
Spotlight,
|
||||
PointLight,
|
||||
SpotLight,
|
||||
DirectionalLight,
|
||||
AreaLight,
|
||||
Camera,
|
||||
Select,
|
||||
SelectAdd,
|
||||
|
@ -52,6 +54,8 @@ enum class lcTrackTool
|
|||
Insert,
|
||||
PointLight,
|
||||
SpotLight,
|
||||
DirectionalLight,
|
||||
AreaLight,
|
||||
Camera,
|
||||
Select,
|
||||
MoveX,
|
||||
|
|
|
@ -675,6 +675,8 @@ bool lcViewManipulator::IsTrackToolAllowed(lcTrackTool TrackTool, quint32 Allowe
|
|||
case lcTrackTool::Insert:
|
||||
case lcTrackTool::PointLight:
|
||||
case lcTrackTool::SpotLight:
|
||||
case lcTrackTool::DirectionalLight:
|
||||
case lcTrackTool::AreaLight:
|
||||
case lcTrackTool::Camera:
|
||||
case lcTrackTool::Select:
|
||||
return true;
|
||||
|
@ -793,7 +795,7 @@ lcTrackTool lcViewManipulator::UpdateSelectMove()
|
|||
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++)
|
||||
{
|
||||
|
|
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_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)
|
||||
#define LC_LIGHT_FOCUS_MASK (LC_LIGHT_POSITION_FOCUSED | LC_LIGHT_TARGET_FOCUSED)
|
||||
|
||||
enum lcLightSection
|
||||
enum lcLightSection : quint32
|
||||
{
|
||||
LC_LIGHT_SECTION_POSITION,
|
||||
LC_LIGHT_SECTION_INVALID = ~0U,
|
||||
LC_LIGHT_SECTION_POSITION = 0,
|
||||
LC_LIGHT_SECTION_TARGET
|
||||
};
|
||||
|
||||
enum class lcLightType
|
||||
{
|
||||
Point,
|
||||
Spot,
|
||||
Directional,
|
||||
Area,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class lcLightAreaShape
|
||||
{
|
||||
Rectangle,
|
||||
Square,
|
||||
Disk,
|
||||
Ellipse,
|
||||
Count
|
||||
};
|
||||
|
||||
class lcLight : public lcObject
|
||||
{
|
||||
public:
|
||||
lcLight(float px, float py, float pz);
|
||||
lcLight(float px, float py, float pz, float tx, float ty, float tz);
|
||||
~lcLight();
|
||||
lcLight(const lcVector3& Position, lcLightType LightType);
|
||||
virtual ~lcLight() = default;
|
||||
|
||||
lcLight(const lcLight&) = delete;
|
||||
lcLight(lcLight&&) = delete;
|
||||
lcLight& operator=(const lcLight&) = delete;
|
||||
lcLight& operator=(lcLight&&) = delete;
|
||||
|
||||
static QString GetLightTypeString(lcLightType LightType);
|
||||
static QString GetAreaShapeString(lcLightAreaShape LightAreaShape);
|
||||
|
||||
bool IsPointLight() const
|
||||
{
|
||||
return (mState & (LC_LIGHT_SPOT | LC_LIGHT_DIRECTIONAL)) == 0;
|
||||
return mLightType == lcLightType::Point;
|
||||
}
|
||||
|
||||
bool IsSpotLight() const
|
||||
{
|
||||
return (mState & LC_LIGHT_SPOT) != 0;
|
||||
return mLightType == lcLightType::Spot;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
return (mState & LC_LIGHT_SELECTION_MASK) != 0;
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
bool IsSelected(quint32 Section) const override
|
||||
{
|
||||
switch (Section)
|
||||
{
|
||||
case LC_LIGHT_SECTION_POSITION:
|
||||
return (mState & LC_LIGHT_POSITION_SELECTED) != 0;
|
||||
break;
|
||||
Q_UNUSED(Section);
|
||||
|
||||
case LC_LIGHT_SECTION_TARGET:
|
||||
return (mState & LC_LIGHT_TARGET_SELECTED) != 0;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
void SetSelected(bool Selected) override
|
||||
{
|
||||
if (Selected)
|
||||
{
|
||||
if (IsPointLight())
|
||||
mState |= LC_LIGHT_POSITION_SELECTED;
|
||||
else
|
||||
mState |= LC_LIGHT_SELECTION_MASK;
|
||||
}
|
||||
else
|
||||
mState &= ~(LC_LIGHT_SELECTION_MASK | LC_LIGHT_FOCUS_MASK);
|
||||
mSelected = Selected;
|
||||
|
||||
if (!Selected)
|
||||
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||
}
|
||||
|
||||
void SetSelected(quint32 Section, bool Selected) override
|
||||
{
|
||||
switch (Section)
|
||||
{
|
||||
case LC_LIGHT_SECTION_POSITION:
|
||||
if (Selected)
|
||||
mState |= LC_LIGHT_POSITION_SELECTED;
|
||||
else
|
||||
mState &= ~(LC_LIGHT_POSITION_SELECTED | LC_LIGHT_POSITION_FOCUSED);
|
||||
break;
|
||||
Q_UNUSED(Section);
|
||||
|
||||
case LC_LIGHT_SECTION_TARGET:
|
||||
if (Selected)
|
||||
{
|
||||
if (!IsPointLight())
|
||||
mState |= LC_LIGHT_TARGET_SELECTED;
|
||||
}
|
||||
else
|
||||
mState &= ~(LC_LIGHT_TARGET_SELECTED | LC_LIGHT_TARGET_FOCUSED);
|
||||
break;
|
||||
}
|
||||
mSelected = Selected;
|
||||
|
||||
if (!Selected)
|
||||
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||
}
|
||||
|
||||
bool IsFocused() const override
|
||||
{
|
||||
return (mState & LC_LIGHT_FOCUS_MASK) != 0;
|
||||
return mFocusedSection != LC_LIGHT_SECTION_INVALID;
|
||||
}
|
||||
|
||||
bool IsFocused(quint32 Section) const override
|
||||
{
|
||||
switch (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;
|
||||
return mFocusedSection == Section;
|
||||
}
|
||||
|
||||
void SetFocused(quint32 Section, bool Focused) override
|
||||
{
|
||||
switch (Section)
|
||||
if (Focused)
|
||||
{
|
||||
case LC_LIGHT_SECTION_POSITION:
|
||||
if (Focused)
|
||||
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;
|
||||
mFocusedSection = Section;
|
||||
mSelected = true;
|
||||
}
|
||||
else
|
||||
mFocusedSection = LC_LIGHT_SECTION_INVALID;
|
||||
}
|
||||
|
||||
quint32 GetFocusSection() const override
|
||||
{
|
||||
if (mState & LC_LIGHT_POSITION_FOCUSED)
|
||||
return LC_LIGHT_SECTION_POSITION;
|
||||
|
||||
if (!IsPointLight() && (mState & LC_LIGHT_TARGET_FOCUSED))
|
||||
return LC_LIGHT_SECTION_TARGET;
|
||||
|
||||
return ~0U;
|
||||
return mFocusedSection;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
switch (Section)
|
||||
{
|
||||
case LC_LIGHT_SECTION_POSITION:
|
||||
return mPosition;
|
||||
if (Section == LC_LIGHT_SECTION_POSITION)
|
||||
return mWorldMatrix.GetTranslation();
|
||||
|
||||
case LC_LIGHT_SECTION_TARGET:
|
||||
return mTargetPosition;
|
||||
}
|
||||
if (Section == LC_LIGHT_SECTION_TARGET)
|
||||
return lcMul31(lcVector3(0.0f, 0.0f, -mTargetDistance), mWorldMatrix);
|
||||
|
||||
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;
|
||||
bool ParseLDrawLine(QTextStream& Stream);
|
||||
|
||||
public:
|
||||
void RayTest(lcObjectRayTest& ObjectRayTest) const override;
|
||||
|
@ -189,7 +217,91 @@ public:
|
|||
void RemoveTime(lcStep Start, lcStep Time);
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -198,36 +310,57 @@ public:
|
|||
|
||||
void CompareBoundingBox(lcVector3& Min, lcVector3& Max);
|
||||
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);
|
||||
void CreateName(const lcArray<lcLight*>& Lights);
|
||||
|
||||
// Temporary parameters
|
||||
lcMatrix44 mWorldLight;
|
||||
lcVector3 mPosition;
|
||||
lcVector3 mTargetPosition;
|
||||
lcVector4 mAmbientColor;
|
||||
lcVector4 mDiffuseColor;
|
||||
lcVector4 mSpecularColor;
|
||||
lcVector3 mAttenuation;
|
||||
float mSpotCutoff;
|
||||
float mSpotExponent;
|
||||
lcMatrix44 mWorldMatrix;
|
||||
|
||||
protected:
|
||||
lcObjectKeyArray<lcVector3> mPositionKeys;
|
||||
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 UpdateLightType();
|
||||
|
||||
void DrawPointLight(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;
|
||||
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 "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)
|
||||
: 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>
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
Stream << QLatin1String("0 !LEOCAD ") << KeyName << Key.Step << ' ';
|
||||
Stream << QLatin1String("0 !LEOCAD ") << ObjectName << ' ' << VariableName << "_KEY " << Key.Step << ' ';
|
||||
|
||||
for (int ValueIdx = 0; ValueIdx < Count; ValueIdx++)
|
||||
Stream << ((float*)&Key.Value)[ValueIdx] << ' ';
|
||||
SaveFloatValue(Stream, Key.Value);
|
||||
|
||||
Stream << QLatin1String("\r\n");
|
||||
}
|
||||
|
@ -168,3 +172,39 @@ void lcObjectKeyArray<T>::RemoveTime(lcStep Start, lcStep Time)
|
|||
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();
|
||||
}
|
||||
|
||||
void SaveKeysLDraw(QTextStream& Stream, const char* KeyName) const;
|
||||
void SaveKeysLDraw(QTextStream& Stream, const char* ObjectName, const char* VariableName) const;
|
||||
void LoadKeysLDraw(QTextStream& Stream);
|
||||
const T& CalculateKey(lcStep Step) const;
|
||||
void ChangeKey(const T& Value, lcStep Step, bool AddKey);
|
||||
|
@ -79,15 +79,18 @@ struct lcObjectBoxTest
|
|||
lcArray<lcObject*> Objects;
|
||||
};
|
||||
|
||||
#define LC_OBJECT_TRANSFORM_MOVE_X 0x001
|
||||
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
|
||||
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
|
||||
#define LC_OBJECT_TRANSFORM_ROTATE_X 0x010
|
||||
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
|
||||
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
|
||||
#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_MOVE_X 0x001
|
||||
#define LC_OBJECT_TRANSFORM_MOVE_Y 0x002
|
||||
#define LC_OBJECT_TRANSFORM_MOVE_Z 0x004
|
||||
#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_X 0x010
|
||||
#define LC_OBJECT_TRANSFORM_ROTATE_Y 0x020
|
||||
#define LC_OBJECT_TRANSFORM_ROTATE_Z 0x040
|
||||
#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_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
|
||||
{
|
||||
|
@ -138,7 +141,12 @@ public:
|
|||
virtual void RemoveKeyFrames() = 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:
|
||||
lcObjectType mObjectType;
|
||||
};
|
||||
|
||||
|
|
|
@ -125,10 +125,10 @@ void lcPiece::SaveLDraw(QTextStream& Stream) const
|
|||
}
|
||||
|
||||
if (mPositionKeys.GetSize() > 1)
|
||||
mPositionKeys.SaveKeysLDraw(Stream, "PIECE POSITION_KEY ");
|
||||
mPositionKeys.SaveKeysLDraw(Stream, "PIECE", "POSITION");
|
||||
|
||||
if (mRotationKeys.GetSize() > 1)
|
||||
mRotationKeys.SaveKeysLDraw(Stream, "PIECE ROTATION_KEY ");
|
||||
mRotationKeys.SaveKeysLDraw(Stream, "PIECE", "ROTATION");
|
||||
|
||||
Stream << "1 " << mColorCode << ' ';
|
||||
|
||||
|
@ -835,12 +835,10 @@ void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix)
|
|||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
|
@ -850,10 +848,10 @@ quint32 lcPiece::GetAllowedTransforms() const
|
|||
return LC_OBJECT_TRANSFORM_MOVE_Z;
|
||||
|
||||
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())
|
||||
return Move;
|
||||
return LC_OBJECT_TRANSFORM_MOVE_XYZ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
void SetSelected(bool Selected) override
|
||||
{
|
||||
mSelected = Selected;
|
||||
|
||||
if (!Selected)
|
||||
mFocusedSection = LC_PIECE_SECTION_INVALID;
|
||||
}
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
Q_UNUSED(Section);
|
||||
|
||||
mSelected = Selected;
|
||||
|
||||
if (!Selected)
|
||||
mFocusedSection = LC_PIECE_SECTION_INVALID;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "project.h"
|
||||
#include "lc_instructions.h"
|
||||
#include "image.h"
|
||||
#include "light.h"
|
||||
#include "lc_mainwindow.h"
|
||||
#include "lc_view.h"
|
||||
#include "lc_library.h"
|
||||
|
@ -1828,15 +1829,6 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
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
|
||||
{
|
||||
LGEO_PIECE_LGEO = 0x01,
|
||||
|
@ -1855,10 +1847,402 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
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());
|
||||
|
||||
if (!TableFile.Open(QIODevice::ReadOnly))
|
||||
|
@ -1869,6 +2253,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
|
||||
while (TableFile.ReadLine(Line, sizeof(Line)))
|
||||
{
|
||||
|
||||
char Src[129], Dst[129], Flags[11];
|
||||
|
||||
if (*Line == ';')
|
||||
|
@ -1877,20 +2262,22 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
if (sscanf(Line,"%128s%128s%10s", Src, Dst, Flags) != 3)
|
||||
continue;
|
||||
|
||||
strcat(Src, ".dat");
|
||||
strncat(Src, ".dat", 4);
|
||||
|
||||
PieceInfo* Info = Library->FindPiece(Src, nullptr, false, false);
|
||||
if (!Info)
|
||||
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];
|
||||
Entry.second |= LGEO_PIECE_LGEO;
|
||||
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];
|
||||
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));
|
||||
return false;
|
||||
}
|
||||
|
||||
while (ColorFile.ReadLine(Line, sizeof(Line)))
|
||||
while (LgeoColorFile.ReadLine(Line, sizeof(Line)))
|
||||
{
|
||||
char Name[1024], Flags[1024];
|
||||
int Code;
|
||||
|
@ -1924,20 +2311,82 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
if (sscanf(Line,"%d%s%s", &Code, Name, Flags) != 3)
|
||||
continue;
|
||||
|
||||
size_t Color = lcGetColorIndex(Code);
|
||||
if (Color >= NumColors)
|
||||
size_t ColorIdx = lcGetColorIndex(Code);
|
||||
if (ColorIdx >= NumColors)
|
||||
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;
|
||||
|
||||
if (!LGEOPath.isEmpty())
|
||||
if (UseLGEO)
|
||||
{
|
||||
POVFile.WriteLine("#include \"lg_defs.inc\"\n#include \"lg_color.inc\"\n\n");
|
||||
|
||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1966,29 +2415,6 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
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;
|
||||
ColorTablePointer.resize(NumColors);
|
||||
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])
|
||||
{
|
||||
strcpy(Name, ModelPart.Info->mFileName);
|
||||
strncpy(Name, ModelPart.Info->mFileName, sizeof(Name));
|
||||
|
||||
for (char* c = Name; *c; c++)
|
||||
if (*c == '-' || *c == '.')
|
||||
|
@ -2006,7 +2432,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
{
|
||||
char Suffix[32];
|
||||
sprintf(Suffix, "_%p", ModelPart.Mesh);
|
||||
strncat(Name, Suffix, sizeof(Name) - 1);
|
||||
strncat(Name, Suffix, sizeof(Name) - strlen(Name) - 1);
|
||||
Name[sizeof(Name) - 1] = 0;
|
||||
}
|
||||
};
|
||||
|
@ -2027,7 +2453,7 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
if (!ModelPart.Mesh)
|
||||
{
|
||||
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);
|
||||
Entry.first[sizeof(Entry.first) - 1] = 0;
|
||||
}
|
||||
|
@ -2038,65 +2464,30 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
POVFile.WriteLine(Line);
|
||||
}
|
||||
|
||||
const lcCamera* Camera = gMainWindow->GetActiveView()->GetCamera();
|
||||
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);
|
||||
sprintf(Line, "#declare %s = union {\n", TopModelName.toLatin1().constData());
|
||||
POVFile.WriteLine(Line);
|
||||
|
||||
for (const lcModelPartsEntry& ModelPart : ModelParts)
|
||||
{
|
||||
int Color = ModelPart.ColorIndex;
|
||||
const char* Suffix = lcIsColorTranslucent(Color) ? "_clear" : "";
|
||||
int ColorIdx = ModelPart.ColorIndex;
|
||||
const char* Suffix = lcIsColorTranslucent(ColorIdx) ? "_clear" : "";
|
||||
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)
|
||||
{
|
||||
std::pair<char[LC_PIECE_NAME_LEN + 1], int>& Entry = PieceTable[ModelPart.Info];
|
||||
|
||||
if (Entry.second & LGEO_PIECE_SLOPE)
|
||||
{
|
||||
sprintf(Line, "merge {\n object {\n %s%s\n texture { %s }\n }\n"
|
||||
" object {\n %s_slope\n texture { %s normal { bumps 0.3 scale 0.02 } }\n }\n"
|
||||
" matrix <%.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f>\n}\n",
|
||||
Entry.first, Suffix, ColorTable[Color].data(), Entry.first, ColorTable[Color].data(),
|
||||
sprintf(Line,
|
||||
" merge {\n object {\n %s%s\n %s { %s }\n }\n"
|
||||
" object {\n %s_slope\n texture {\n %s normal { bumps 0.3 scale 0.02 }\n }\n }\n"
|
||||
" 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);
|
||||
}
|
||||
else
|
||||
|
@ -2104,8 +2495,8 @@ bool Project::ExportPOVRay(const QString& FileName)
|
|||
if (!ModelPart.Info || !ModelPart.Info->GetMesh())
|
||||
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",
|
||||
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);
|
||||
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, 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];
|
||||
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",
|
||||
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);
|
||||
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, 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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2239,7 +2646,7 @@ void Project::SaveImage()
|
|||
|
||||
if (Dialog.exec() != QDialog::Accepted)
|
||||
return;
|
||||
|
||||
|
||||
QString Extension = QFileInfo(Dialog.mFileName).suffix();
|
||||
|
||||
if (!Extension.isEmpty())
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>resources/action_arealight_16.png</file>
|
||||
<file>resources/action_delete_16.png</file>
|
||||
<file>resources/action_insert_16.png</file>
|
||||
<file>resources/action_light_16.png</file>
|
||||
|
@ -9,6 +10,7 @@
|
|||
<file>resources/action_rotate_16.png</file>
|
||||
<file>resources/action_select_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/edit_copy_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_povray_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_color_picker.png</file>
|
||||
<file>resources/action_color_picker_16.png</file>
|
||||
|
@ -41,9 +44,11 @@
|
|||
<file>resources/action_rotate_view.png</file>
|
||||
<file>resources/action_select.png</file>
|
||||
<file>resources/action_spotlight.png</file>
|
||||
<file>resources/action_sunlight.png</file>
|
||||
<file>resources/action_zoom.png</file>
|
||||
<file>resources/action_zoom_extents.png</file>
|
||||
<file>resources/action_zoom_region.png</file>
|
||||
<file>resources/cursor_arealight.png</file>
|
||||
<file>resources/cursor_camera.png</file>
|
||||
<file>resources/cursor_color_picker.png</file>
|
||||
<file>resources/cursor_delete.png</file>
|
||||
|
@ -61,6 +66,7 @@
|
|||
<file>resources/cursor_select_add.png</file>
|
||||
<file>resources/cursor_select_remove.png</file>
|
||||
<file>resources/cursor_spotlight.png</file>
|
||||
<file>resources/cursor_sunlight.png</file>
|
||||
<file>resources/cursor_zoom.png</file>
|
||||
<file>resources/cursor_zoom_region.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));
|
||||
painter->save();
|
||||
painter->setPen(QPen(color));
|
||||
|
||||
|
||||
if (!m_treeWidget || (!m_treeWidget->lastColumn(index.column()) && hasValue))
|
||||
{
|
||||
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_uncheckedIcon = drawCheckBox(false);
|
||||
|
||||
m_delegate = new lcQPropertiesTreeDelegate(parent);
|
||||
m_delegate->setTreeWidget(this);
|
||||
setItemDelegate(m_delegate);
|
||||
mDelegate = new lcQPropertiesTreeDelegate(parent);
|
||||
mDelegate->setTreeWidget(this);
|
||||
setItemDelegate(mDelegate);
|
||||
|
||||
SetEmpty();
|
||||
|
||||
|
@ -264,7 +264,7 @@ void lcQPropertiesTree::keyPressEvent(QKeyEvent *event)
|
|||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Space: // Trigger Edit
|
||||
if (!m_delegate->editedItem())
|
||||
if (!mDelegate->editedItem())
|
||||
{
|
||||
if (const QTreeWidgetItem *item = currentItem())
|
||||
{
|
||||
|
@ -299,8 +299,8 @@ void lcQPropertiesTree::mousePressEvent(QMouseEvent *event)
|
|||
|
||||
if (item)
|
||||
{
|
||||
if ((item != m_delegate->editedItem()) && (event->button() == Qt::LeftButton) && (header()->logicalIndexAt(event->pos().x()) == 1) &&
|
||||
((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled)))
|
||||
if ((item != mDelegate->editedItem()) && (event->button() == Qt::LeftButton) && (header()->logicalIndexAt(event->pos().x()) == 1) &&
|
||||
((item->flags() & (Qt::ItemIsEditable | Qt::ItemIsEnabled)) == (Qt::ItemIsEditable | Qt::ItemIsEnabled)))
|
||||
editItem(item, 1);
|
||||
}
|
||||
}
|
||||
|
@ -423,59 +423,63 @@ protected:
|
|||
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:
|
||||
return nullptr;
|
||||
|
||||
case PropertyBool:
|
||||
{
|
||||
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;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
case PropertyFloat:
|
||||
{
|
||||
QLineEdit *editor = new QLineEdit(parent);
|
||||
float value = item->data(0, PropertyValueRole).toFloat();
|
||||
QLineEdit* Editor = new QLineEdit(Parent);
|
||||
float Value = Item->data(0, PropertyValueRole).toFloat();
|
||||
QPointF Range = Item->data(0, PropertyRangeRole).toPointF();
|
||||
|
||||
editor->setValidator(new QDoubleValidator(editor));
|
||||
editor->setText(lcFormatValueLocalized(value));
|
||||
Editor->setValidator(Range.isNull() ? new QDoubleValidator(Editor) : new QDoubleValidator(Range.x(), Range.y(), 1, Editor));
|
||||
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:
|
||||
{
|
||||
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 Hide = partHide->data(0, PropertyValueRole).toUInt();
|
||||
|
||||
if (Show && Hide)
|
||||
{
|
||||
if (item == partShow)
|
||||
if (Item == partShow)
|
||||
Editor->setValidator(new lcStepValidator(1, Hide - 1, false));
|
||||
else
|
||||
Editor->setValidator(new lcStepValidator(Show + 1, LC_STEP_MAX, true));
|
||||
}
|
||||
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));
|
||||
|
||||
connect(Editor, SIGNAL(returnPressed()), this, SLOT(slotReturnPressed()));
|
||||
|
@ -485,8 +489,8 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
|||
|
||||
case PropertyString:
|
||||
{
|
||||
QLineEdit *editor = new QLineEdit(parent);
|
||||
QString value = item->data(0, PropertyValueRole).toString();
|
||||
QLineEdit *editor = new QLineEdit(Parent);
|
||||
QString value = Item->data(0, PropertyValueRole).toString();
|
||||
|
||||
editor->setText(value);
|
||||
|
||||
|
@ -495,10 +499,49 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
|||
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:
|
||||
{
|
||||
QPushButton *editor = new QPushButton(parent);
|
||||
int value = item->data(0, PropertyValueRole).toInt();
|
||||
QPushButton *Editor = new QPushButton(Parent);
|
||||
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);
|
||||
|
||||
|
@ -509,7 +552,7 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
|||
|
||||
case PropertyPart:
|
||||
{
|
||||
QComboBox *editor = new QComboBox(parent);
|
||||
QComboBox *editor = new QComboBox(Parent);
|
||||
|
||||
editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||
editor->setMinimumContentsLength(1);
|
||||
|
@ -537,7 +580,7 @@ QWidget *lcQPropertiesTree::createEditor(QWidget *parent, QTreeWidgetItem *item)
|
|||
for (PieceInfo* Info : SortedPieces)
|
||||
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)));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
QTreeWidgetItem* Item = m_delegate->editedItem();
|
||||
QTreeWidgetItem* Item = mDelegate->editedItem();
|
||||
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 == cameraOrtho)
|
||||
if (Item == mLightCastShadowItem)
|
||||
{
|
||||
Model->SetCameraOrthographic(Camera, Value);
|
||||
Model->SetLightCastShadow(Light, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -591,53 +650,57 @@ void lcQPropertiesTree::slotToggled(bool Value)
|
|||
void lcQPropertiesTree::slotReturnPressed()
|
||||
{
|
||||
QLineEdit* Editor = (QLineEdit*)sender();
|
||||
QTreeWidgetItem* Item = m_delegate->editedItem();
|
||||
QTreeWidgetItem* Item = mDelegate->editedItem();
|
||||
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)
|
||||
{
|
||||
lcPiece* Piece = (mFocus && mFocus->IsPiece()) ? (lcPiece*)mFocus : nullptr;
|
||||
|
||||
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)
|
||||
if (Item == partShow)
|
||||
{
|
||||
bool Ok = false;
|
||||
lcStep Step = Editor->text().toUInt(&Ok);
|
||||
|
@ -736,7 +799,7 @@ void lcQPropertiesTree::slotReturnPressed()
|
|||
|
||||
Model->SetCameraZFar(Camera, Value);
|
||||
}
|
||||
else if (Item == cameraName)
|
||||
else if (Item == mCameraNameItem)
|
||||
{
|
||||
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)
|
||||
{
|
||||
QTreeWidgetItem* Item = m_delegate->editedItem();
|
||||
QTreeWidgetItem* Item = mDelegate->editedItem();
|
||||
lcModel* Model = gMainWindow->GetActiveModel();
|
||||
|
||||
if (mWidgetMode == LC_PROPERTY_WIDGET_PIECE)
|
||||
{
|
||||
if (Item == partColor)
|
||||
if (Item == mPieceColorItem)
|
||||
{
|
||||
Model->SetSelectedPiecesColorIndex(Value);
|
||||
|
||||
QPushButton *editor = (QPushButton*)m_delegate->editor();
|
||||
QPushButton *editor = (QPushButton*)mDelegate->editor();
|
||||
updateColorEditor(editor, Value);
|
||||
}
|
||||
else if (Item == partID)
|
||||
else if (Item == mPieceIdItem)
|
||||
{
|
||||
QComboBox *editor = (QComboBox*)sender();
|
||||
|
||||
|
@ -775,6 +914,37 @@ void lcQPropertiesTree::slotSetValue(int Value)
|
|||
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()
|
||||
|
@ -822,6 +992,28 @@ void lcQPropertiesTree::slotColorButtonClicked()
|
|||
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 *newItem;
|
||||
|
@ -848,20 +1040,13 @@ void lcQPropertiesTree::SetEmpty()
|
|||
{
|
||||
clear();
|
||||
|
||||
partPosition = nullptr;
|
||||
partPositionX = nullptr;
|
||||
partPositionY = nullptr;
|
||||
partPositionZ = nullptr;
|
||||
partRotation = nullptr;
|
||||
partRotationX = nullptr;
|
||||
partRotationY = nullptr;
|
||||
partRotationZ = nullptr;
|
||||
mPieceAttributesItem = nullptr;
|
||||
partVisibility = nullptr;
|
||||
partShow = nullptr;
|
||||
partHide = nullptr;
|
||||
partAppearance = nullptr;
|
||||
partColor = nullptr;
|
||||
partID = nullptr;
|
||||
mPieceColorItem = nullptr;
|
||||
mPieceIdItem = nullptr;
|
||||
|
||||
cameraPosition = nullptr;
|
||||
cameraPositionX = nullptr;
|
||||
|
@ -875,12 +1060,38 @@ void lcQPropertiesTree::SetEmpty()
|
|||
cameraUpX = nullptr;
|
||||
cameraUpY = nullptr;
|
||||
cameraUpZ = nullptr;
|
||||
cameraSettings = nullptr;
|
||||
cameraOrtho = nullptr;
|
||||
mCameraAttributesItem = nullptr;
|
||||
mCameraProjectionItem = nullptr;
|
||||
cameraFOV = nullptr;
|
||||
cameraNear = 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;
|
||||
mFocus = nullptr;
|
||||
|
@ -892,23 +1103,23 @@ void lcQPropertiesTree::SetPiece(const lcArray<lcObject*>& Selection, lcObject*
|
|||
{
|
||||
SetEmpty();
|
||||
|
||||
partPosition = addProperty(nullptr, tr("Position"), PropertyGroup);
|
||||
partPositionX = addProperty(partPosition, tr("X"), PropertyFloat);
|
||||
partPositionY = addProperty(partPosition, tr("Y"), PropertyFloat);
|
||||
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);
|
||||
mPieceAttributesItem = addProperty(nullptr, tr("Piece Attributes"), PropertyGroup);
|
||||
mPieceIdItem = addProperty(mPieceAttributesItem, tr("Part"), PropertyPart);
|
||||
mPieceColorItem = addProperty(mPieceAttributesItem, tr("Color"), PropertyPieceColor);
|
||||
|
||||
partVisibility = addProperty(nullptr, tr("Visible Steps"), PropertyGroup);
|
||||
partShow = addProperty(partVisibility, tr("Show"), PropertyStep);
|
||||
partHide = addProperty(partVisibility, tr("Hide"), PropertyStep);
|
||||
|
||||
partAppearance = addProperty(nullptr, tr("Appearance"), PropertyGroup);
|
||||
partColor = addProperty(partAppearance, tr("Color"), PropertyColor);
|
||||
partID = addProperty(partAppearance, tr("Part"), PropertyPart);
|
||||
mPositionItem = addProperty(nullptr, tr("Position"), PropertyGroup);
|
||||
mPositionXItem = addProperty(mPositionItem, tr("X"), PropertyFloat);
|
||||
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;
|
||||
}
|
||||
|
@ -919,25 +1130,29 @@ void lcQPropertiesTree::SetPiece(const lcArray<lcObject*>& Selection, lcObject*
|
|||
|
||||
lcVector3 Position;
|
||||
lcMatrix33 RelativeRotation;
|
||||
|
||||
Model->GetMoveRotateTransform(Position, RelativeRotation);
|
||||
partPositionX->setText(1, lcFormatValueLocalized(Position[0]));
|
||||
partPositionX->setData(0, PropertyValueRole, Position[0]);
|
||||
partPositionY->setText(1, lcFormatValueLocalized(Position[1]));
|
||||
partPositionY->setData(0, PropertyValueRole, Position[1]);
|
||||
partPositionZ->setText(1, lcFormatValueLocalized(Position[2]));
|
||||
partPositionZ->setData(0, PropertyValueRole, Position[2]);
|
||||
|
||||
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]);
|
||||
|
||||
lcVector3 Rotation;
|
||||
|
||||
if (Piece)
|
||||
Rotation = lcMatrix44ToEulerAngles(Piece->mModelWorld) * LC_RTOD;
|
||||
else
|
||||
Rotation = lcVector3(0.0f, 0.0f, 0.0f);
|
||||
partRotationX->setText(1, lcFormatValueLocalized(Rotation[0]));
|
||||
partRotationX->setData(0, PropertyValueRole, Rotation[0]);
|
||||
partRotationY->setText(1, lcFormatValueLocalized(Rotation[1]));
|
||||
partRotationY->setData(0, PropertyValueRole, Rotation[1]);
|
||||
partRotationZ->setText(1, lcFormatValueLocalized(Rotation[2]));
|
||||
partRotationZ->setData(0, PropertyValueRole, Rotation[2]);
|
||||
|
||||
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]);
|
||||
|
||||
lcStep Show = 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.end();
|
||||
|
||||
partColor->setIcon(1, QIcon(QPixmap::fromImage(img)));
|
||||
partColor->setText(1, color->Name);
|
||||
partColor->setData(0, PropertyValueRole, ColorIndex);
|
||||
mPieceColorItem->setIcon(1, QIcon(QPixmap::fromImage(img)));
|
||||
mPieceColorItem->setText(1, color->Name);
|
||||
mPieceColorItem->setData(0, PropertyValueRole, ColorIndex);
|
||||
|
||||
QString text = Info ? Info->m_strDescription : QString();
|
||||
partID->setText(1, text);
|
||||
partID->setToolTip(1, text);
|
||||
partID->setData(0, PropertyValueRole, QVariant::fromValue((void*)Info));
|
||||
mPieceIdItem->setText(1, text);
|
||||
mPieceIdItem->setToolTip(1, text);
|
||||
mPieceIdItem->setData(0, PropertyValueRole, QVariant::fromValue((void*)Info));
|
||||
}
|
||||
|
||||
void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
||||
|
@ -1024,6 +1239,13 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
|||
{
|
||||
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);
|
||||
cameraPositionX = addProperty(cameraPosition, tr("X"), PropertyFloat);
|
||||
cameraPositionY = addProperty(cameraPosition, tr("Y"), PropertyFloat);
|
||||
|
@ -1039,13 +1261,6 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
|||
cameraUpY = addProperty(cameraUp, tr("Y"), 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;
|
||||
}
|
||||
|
||||
|
@ -1095,8 +1310,8 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
|||
cameraUpZ->setText(1, lcFormatValueLocalized(UpVector[2]));
|
||||
cameraUpZ->setData(0, PropertyValueRole, UpVector[2]);
|
||||
|
||||
cameraOrtho->setText(1, Ortho ? "True" : "False");
|
||||
cameraOrtho->setData(0, PropertyValueRole, Ortho);
|
||||
mCameraProjectionItem->setText(1, Ortho ? tr("Orthographic") : tr("Perspective"));
|
||||
mCameraProjectionItem->setData(0, PropertyValueRole, Ortho);
|
||||
cameraFOV->setText(1, lcFormatValueLocalized(FoV));
|
||||
cameraFOV->setData(0, PropertyValueRole, FoV);
|
||||
cameraNear->setText(1, lcFormatValueLocalized(ZNear));
|
||||
|
@ -1104,18 +1319,259 @@ void lcQPropertiesTree::SetCamera(lcObject* Focus)
|
|||
cameraFar->setText(1, lcFormatValueLocalized(ZFar));
|
||||
cameraFar->setData(0, PropertyValueRole, ZFar);
|
||||
|
||||
cameraName->setText(1, Name);
|
||||
cameraName->setData(0, PropertyValueRole, Name);
|
||||
mCameraNameItem->setText(1, Name);
|
||||
mCameraNameItem->setData(0, PropertyValueRole, Name);
|
||||
}
|
||||
|
||||
void lcQPropertiesTree::SetLight(lcObject* Focus)
|
||||
{
|
||||
Q_UNUSED(Focus);
|
||||
lcLight* Light = (Focus && Focus->IsLight()) ? (lcLight*)Focus : nullptr;
|
||||
|
||||
SetEmpty();
|
||||
mFocus = nullptr;
|
||||
QString Name = tr("Light");
|
||||
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()
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
enum
|
||||
{
|
||||
PropertyTypeRole = Qt::UserRole,
|
||||
PropertyValueRole
|
||||
PropertyValueRole,
|
||||
PropertyRangeRole
|
||||
};
|
||||
|
||||
enum PropertyType
|
||||
|
@ -44,9 +45,12 @@ public:
|
|||
PropertyGroup,
|
||||
PropertyBool,
|
||||
PropertyFloat,
|
||||
PropertyInteger,
|
||||
PropertyStep,
|
||||
PropertyString,
|
||||
PropertyStringList,
|
||||
PropertyColor,
|
||||
PropertyPieceColor,
|
||||
PropertyPart
|
||||
};
|
||||
|
||||
|
@ -55,12 +59,14 @@ protected slots:
|
|||
void slotReturnPressed();
|
||||
void slotSetValue(int value);
|
||||
void slotColorButtonClicked();
|
||||
void LightColorButtonClicked();
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
void updateColorEditor(QPushButton *editor, int value) const;
|
||||
void UpdateLightColorEditor(QPushButton* Editor, QColor Color) const;
|
||||
|
||||
QTreeWidgetItem *addProperty(QTreeWidgetItem *parent, const QString& label, PropertyType propertyType);
|
||||
|
||||
|
@ -70,49 +76,68 @@ protected:
|
|||
void SetLight(lcObject* Focus);
|
||||
void SetMultiple();
|
||||
|
||||
void getPartProperties(lcPartProperties *properties);
|
||||
lcLightType mLightType;
|
||||
|
||||
lcPropertyWidgetMode mWidgetMode;
|
||||
lcObject* mFocus;
|
||||
|
||||
lcQPropertiesTreeDelegate *m_delegate;
|
||||
lcQPropertiesTreeDelegate* mDelegate;
|
||||
QIcon m_expandIcon;
|
||||
QIcon m_checkedIcon;
|
||||
QIcon m_uncheckedIcon;
|
||||
|
||||
QTreeWidgetItem *partPosition;
|
||||
QTreeWidgetItem *partPositionX;
|
||||
QTreeWidgetItem *partPositionY;
|
||||
QTreeWidgetItem *partPositionZ;
|
||||
QTreeWidgetItem *partRotation;
|
||||
QTreeWidgetItem *partRotationX;
|
||||
QTreeWidgetItem *partRotationY;
|
||||
QTreeWidgetItem *partRotationZ;
|
||||
QTreeWidgetItem *partVisibility;
|
||||
QTreeWidgetItem *partShow;
|
||||
QTreeWidgetItem *partHide;
|
||||
QTreeWidgetItem *partAppearance;
|
||||
QTreeWidgetItem *partColor;
|
||||
QTreeWidgetItem *partID;
|
||||
QTreeWidgetItem* mPieceAttributesItem;
|
||||
QTreeWidgetItem* partVisibility;
|
||||
QTreeWidgetItem* partShow;
|
||||
QTreeWidgetItem* partHide;
|
||||
QTreeWidgetItem* partAppearance;
|
||||
QTreeWidgetItem* mPieceColorItem;
|
||||
QTreeWidgetItem* mPieceIdItem;
|
||||
|
||||
QTreeWidgetItem *cameraPosition;
|
||||
QTreeWidgetItem *cameraPositionX;
|
||||
QTreeWidgetItem *cameraPositionY;
|
||||
QTreeWidgetItem *cameraPositionZ;
|
||||
QTreeWidgetItem *cameraTarget;
|
||||
QTreeWidgetItem *cameraTargetX;
|
||||
QTreeWidgetItem *cameraTargetY;
|
||||
QTreeWidgetItem *cameraTargetZ;
|
||||
QTreeWidgetItem *cameraUp;
|
||||
QTreeWidgetItem *cameraUpX;
|
||||
QTreeWidgetItem *cameraUpY;
|
||||
QTreeWidgetItem *cameraUpZ;
|
||||
QTreeWidgetItem *cameraSettings;
|
||||
QTreeWidgetItem *cameraOrtho;
|
||||
QTreeWidgetItem *cameraFOV;
|
||||
QTreeWidgetItem *cameraNear;
|
||||
QTreeWidgetItem *cameraFar;
|
||||
QTreeWidgetItem *cameraName;
|
||||
QTreeWidgetItem* cameraPosition;
|
||||
QTreeWidgetItem* cameraPositionX;
|
||||
QTreeWidgetItem* cameraPositionY;
|
||||
QTreeWidgetItem* cameraPositionZ;
|
||||
QTreeWidgetItem* cameraTarget;
|
||||
QTreeWidgetItem* cameraTargetX;
|
||||
QTreeWidgetItem* cameraTargetY;
|
||||
QTreeWidgetItem* cameraTargetZ;
|
||||
QTreeWidgetItem* cameraUp;
|
||||
QTreeWidgetItem* cameraUpX;
|
||||
QTreeWidgetItem* cameraUpY;
|
||||
QTreeWidgetItem* cameraUpZ;
|
||||
QTreeWidgetItem* mCameraAttributesItem;
|
||||
QTreeWidgetItem* mCameraProjectionItem;
|
||||
QTreeWidgetItem* cameraFOV;
|
||||
QTreeWidgetItem* cameraNear;
|
||||
QTreeWidgetItem* cameraFar;
|
||||
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
|
||||
|
@ -161,4 +186,3 @@ private:
|
|||
mutable QWidget *m_editedWidget;
|
||||
mutable bool m_disablePainting;
|
||||
};
|
||||
|
||||
|
|
|
@ -348,14 +348,6 @@ void lcRenderDialog::on_RenderButton_clicked()
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
if (!LGEOPath.isEmpty())
|
||||
{
|
||||
Arguments.append(QString::fromLatin1("+L%1lg/").arg(LGEOPath));
|
||||
Arguments.append(QString::fromLatin1("+L%1ar/").arg(LGEOPath));
|
||||
}
|
||||
*/
|
||||
|
||||
QString POVRayPath;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -372,6 +364,29 @@ void lcRenderDialog::on_RenderButton_clicked()
|
|||
POVRayPath = QDir::cleanPath(QCoreApplication::applicationDirPath() + QLatin1String("/povray"));
|
||||
#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);
|
||||
#ifdef Q_OS_LINUX
|
||||
connect(mProcess, SIGNAL(readyReadStandardError()), this, SLOT(ReadStdErr()));
|
||||
|
@ -882,11 +897,16 @@ void lcRenderDialog::on_OutputBrowseButton_clicked()
|
|||
|
||||
void lcRenderDialog::on_RenderOutputButton_clicked()
|
||||
{
|
||||
const QString RenderType = mCommand == POVRAY_RENDER ? QLatin1String("POV-Ray") : QLatin1String("Blender");
|
||||
QFileInfo FileInfo(GetStdOutFileName());
|
||||
QFileInfo FileInfo(GetStdErrFileName());
|
||||
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())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
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>
|
||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||
<source>New SpotLight</source>
|
||||
<source>New Spotlight</source>
|
||||
<translation>Nový zdroj osvětlení</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -5501,7 +5501,7 @@ Bitte lesen sie unter https://www.leocad.org nach wie man eine Bibliothek herunt
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||
<source>New SpotLight</source>
|
||||
<source>New Spotlight</source>
|
||||
<translation>Neues Scheinwerferlicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -5577,7 +5577,7 @@ Por favor, visita https://www.leocad.org para saber cómo descargar e instalar u
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||
<source>New SpotLight</source>
|
||||
<source>New Spotlight</source>
|
||||
<translation>nuevo foco</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -5485,7 +5485,7 @@ SVP visitez https://www.leocad.org pour apprendre comment télécharger et insta
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||
<source>New SpotLight</source>
|
||||
<source>New Spotlight</source>
|
||||
<translation>Nouvelle lumière projecteur</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -5412,7 +5412,7 @@ Veja https://www.leocad.org para saber como descarragar e instalar uma bibliotec
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||
<source>New SpotLight</source>
|
||||
<source>New Spotlight</source>
|
||||
<translation>Novo Projector</translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
|
@ -5477,7 +5477,7 @@ Please visit https://www.leocad.org for information on how to download and insta
|
|||
</message>
|
||||
<message>
|
||||
<location filename="../common/lc_model.cpp" line="3957"/>
|
||||
<source>New SpotLight</source>
|
||||
<source>New Spotlight</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
|
|
Loading…
Reference in a new issue