diff --git a/samples/tcl/pathtrace_cube.tcl b/samples/tcl/pathtrace_cube.tcl index ef6e0a22ab..1ef1b248cb 100644 --- a/samples/tcl/pathtrace_cube.tcl +++ b/samples/tcl/pathtrace_cube.tcl @@ -54,16 +54,14 @@ vbsdf s -absorpCoeff 6 # setup first inner box box c 0.3 0.3 0.2 vdisplay -noupdate c -vlocation -noupdate c -setLocation 0.55 0.3 0.0 -vlocation -noupdate c -rotate 0 0 0 0 0 1 -30 +vlocation -noupdate c -reset -rotate 0 0 0 0 0 1 -30 -translate 0.55 0.3 0.0 vsetmaterial -noupdate c plastic vbsdf c -kd 1.0 0.8 0.2 -ks 0.3 -n # setup second inner box box g 0.15 0.15 0.3 vdisplay -noupdate g -vlocation -noupdate g -setLocation 0.7 0.25 0.2 -vlocation -noupdate g -rotate 0 0 0 0 0 1 10 +vlocation -noupdate g -reset -rotate 0 0 0 0 0 1 10 -translate 0.7 0.25 0.2 vsetmaterial -noupdate g glass vbsdf g -absorpColor 0.8 1.0 0.8 vbsdf g -absorpCoeff 6 diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 3db6e673d5..e9638db994 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -3958,7 +3958,8 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, ++anArgIter; aContext->SetLocation (anObj, anObj2->LocalTransformation()); } - else if (anArg == "-rotate") + else if (anArg == "-rotate" + || anArg == "-prerotate") { toPrintInfo = Standard_False; if (anArgIter + 7 >= theArgNb) @@ -3977,10 +3978,18 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, Draw::Atof (theArgVec[anArgIter + 7]) * (M_PI / 180.0)); anArgIter += 7; - aTrsf = anObj->LocalTransformation() * aTrsf; + if (anArg == "-prerotate") + { + aTrsf = anObj->LocalTransformation() * aTrsf; + } + else + { + aTrsf = aTrsf * anObj->LocalTransformation(); + } aContext->SetLocation (anObj, aTrsf); } - else if (anArg == "-translate") + else if (anArg == "-translate" + || anArg == "-pretranslate") { toPrintInfo = Standard_False; gp_Vec aLocVec; @@ -3994,10 +4003,18 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, gp_Trsf aTrsf; aTrsf.SetTranslationPart (aLocVec); - aTrsf = anObj->LocalTransformation() * aTrsf; + if (anArg == "-pretranslate") + { + aTrsf = anObj->LocalTransformation() * aTrsf; + } + else + { + aTrsf = aTrsf * anObj->LocalTransformation(); + } aContext->SetLocation (anObj, aTrsf); } else if (anArg == "-scale" + || anArg == "-prescale" || anArg == "-setscale") { toPrintInfo = Standard_False; @@ -4050,7 +4067,8 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, if (toPrintScale) { - if (anArg == "-setscale") + if (anArg == "-setscale" + || anArg == "-prescale") { Message::SendFail() << "Syntax error at '" << anArg << "'"; return 1; @@ -4081,17 +4099,25 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, if (hasScaleLoc) { aTrsf.SetScale (aScaleLoc, aScale); + } + else + { + aTrsf.SetScaleFactor (aScale); + } + + if (anArg == "-prescale") + { aTrsf = anObj->LocalTransformation() * aTrsf; } else { - aTrsf = anObj->LocalTransformation(); - aTrsf.SetScaleFactor (aTrsf.ScaleFactor() * aScale); + aTrsf = aTrsf * anObj->LocalTransformation(); } aContext->SetLocation (anObj, aTrsf); } } - else if (anArg == "-mirror") + else if (anArg == "-mirror" + || anArg == "-premirror") { toPrintInfo = Standard_False; if (anArgIter + 6 >= theArgNb) @@ -4108,7 +4134,14 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, Draw::Atof(theArgVec[theArgNb - 2]), Draw::Atof(theArgVec[theArgNb - 1])))); anArgIter += 6; - aTrsf = anObj->LocalTransformation() * aTrsf; + if (anArg == "-premirror") + { + aTrsf = anObj->LocalTransformation() * aTrsf; + } + else + { + aTrsf = aTrsf * anObj->LocalTransformation(); + } aContext->SetLocation (anObj, aTrsf); } else if (anArg == "-setrotation" @@ -4141,7 +4174,7 @@ static Standard_Integer VSetLocation (Draw_Interpretor& theDI, aQuatArgs[2].RealValue(), aQuatArgs[3].RealValue()); gp_Trsf aTrsf = anObj->LocalTransformation(); - aTrsf.SetRotation (aQuat); + aTrsf.SetRotationPart (aQuat); aContext->SetLocation (anObj, aTrsf); continue; } @@ -6567,27 +6600,24 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) theCommands.Add ("vlocation", "vlocation name" - "\n\t\t: [-reset]" - "\n\t\t: [-copyFrom otherName]" - "\n\t\t: [-translate X Y [Z]]" - "\n\t\t: [-rotate x y z dx dy dz angle]" - "\n\t\t: [-scale [X Y Z] scale]" - "\n\t\t: [-mirror x y z dx dy dz]" - "\n\t\t: [-setLocation X Y [Z]]" - "\n\t\t: [-setRotation QX QY QZ QW]" - "\n\t\t: [-setScale [X Y Z] scale]" - "\n\t\t: [-inheritParentTrsf {on|off}]" + "\n\t\t: [-reset] [-copyFrom otherName]" + "\n\t\t: [-translate X Y [Z]] [-rotate x y z dx dy dz angle] [-scale [X Y Z] scale]" + "\n\t\t: [-pretranslate X Y [Z]] [-prerotate x y z dx dy dz angle] [-prescale [X Y Z] scale]" + "\n\t\t: [-mirror x y z dx dy dz] [-premirror x y z dx dy dz]" + "\n\t\t: [-setLocation X Y [Z]] [-setRotation QX QY QZ QW] [-setScale [X Y Z] scale]" "\n\t\t: Object local transformation management:" - "\n\t\t: -reset reset transformation to identity" - "\n\t\t: -translate translate object" - "\n\t\t: -rotate applies rotation to local transformation" - "\n\t\t: -scale applies scale to local transformation" - "\n\t\t: -mirror applies mirror to local transformation" - "\n\t\t: -setLocation assign object location" - "\n\t\t: -setRotation assign object rotation (quaternion)" - "\n\t\t: -setScale assign object scale factor" - "\n\t\t: -inheritParentTrsf option to inherit parent" - "\n\t\t: transformation or not (ON by default)", + "\n\t\t: -reset resets transformation to identity" + "\n\t\t: -translate applies translation vector" + "\n\t\t: -rotate applies rotation around axis" + "\n\t\t: -scale applies scale factor with optional anchor" + "\n\t\t: -mirror applies mirror transformation" + "\n\t\t: -pretranslate pre-multiplies translation vector" + "\n\t\t: -prerotate pre-multiplies rotation around axis" + "\n\t\t: -prescale pre-multiplies scale transformation" + "\n\t\t: -premirror pre-multiplies mirror transformation" + "\n\t\t: -setLocation overrides translation part" + "\n\t\t: -setRotation overrides rotation part with specified quaternion" + "\n\t\t: -setScale overrides scale factor", __FILE__, VSetLocation, group); theCommands.Add ("vsetlocation", "alias for vlocation", diff --git a/src/gp/gp_Trsf.cxx b/src/gp/gp_Trsf.cxx index 9a4e299de5..1ddf2eb304 100644 --- a/src/gp/gp_Trsf.cxx +++ b/src/gp/gp_Trsf.cxx @@ -129,6 +129,57 @@ void gp_Trsf::SetRotation (const gp_Quaternion& R) matrix = R.GetMatrix(); } +//======================================================================= +//function : SetRotationPart +//purpose : +//======================================================================= +void gp_Trsf::SetRotationPart (const gp_Quaternion& theR) +{ + const bool hasRotation = !theR.IsEqual (gp_Quaternion()); + if (hasRotation) + { + matrix = theR.GetMatrix(); + } + else + { + matrix.SetIdentity(); + } + + switch (shape) + { + case gp_Identity: + { + if (hasRotation) + { + shape = gp_Rotation; + } + break; + } + case gp_Rotation: + { + if (!hasRotation) + { + shape = gp_Identity; + } + break; + } + case gp_Translation: + case gp_PntMirror: + case gp_Ax1Mirror: + case gp_Ax2Mirror: + case gp_Scale: + case gp_CompoundTrsf: + case gp_Other: + { + if (hasRotation) + { + shape = gp_CompoundTrsf; + } + break; + } + } +} + //======================================================================= //function : SetScale //purpose : diff --git a/src/gp/gp_Trsf.hxx b/src/gp/gp_Trsf.hxx index 82c15e91c1..5148d4d95b 100644 --- a/src/gp/gp_Trsf.hxx +++ b/src/gp/gp_Trsf.hxx @@ -110,13 +110,14 @@ public: //! A1 is the rotation axis and Ang is the angular value of the //! rotation in radians. Standard_EXPORT void SetRotation (const gp_Ax1& A1, const Standard_Real Ang); - //! Changes the transformation into a rotation defined by quaternion. //! Note that rotation is performed around origin, i.e. //! no translation is involved. Standard_EXPORT void SetRotation (const gp_Quaternion& R); - + + //! Replaces the rotation part with specified quaternion. + Standard_EXPORT void SetRotationPart (const gp_Quaternion& R); //! Changes the transformation into a scale. //! P is the center of the scale and S is the scaling value. diff --git a/tests/bugs/vis/bug25276 b/tests/bugs/vis/bug25276 index 85c14da691..45b4cd71cd 100644 --- a/tests/bugs/vis/bug25276 +++ b/tests/bugs/vis/bug25276 @@ -1,12 +1,9 @@ puts "============" -puts "OCC25276" +puts "0025276: Visualization - Lighting is broken if some kinds of transformation applied to a shape" puts "============" puts "" -####################################################################### -# Visualization - Lighting is broken if some kinds of transformation applied to a shape -####################################################################### -pload ALL +pload MODELING VISUALIZATION vinit box b1 1 6 1 vsetdispmode 1 @@ -21,10 +18,10 @@ vconnect z1 0 0 0 z vlocation z1 -translate 10 0 0 vconnect z2 0 10 0 z -vlocation z2 -rotate 0 0 0 1 0 0 90 +vlocation z2 -prerotate 0 0 0 1 0 0 90 vconnect z3 -10 0 0 z -vlocation z3 -scale 0 0 0 0.5 +vlocation z3 -prescale 0 0 0 0.5 vconnect z4 0 0 0 z vlocation z4 -copyFrom z3 diff --git a/tests/bugs/vis/bug31673 b/tests/bugs/vis/bug31673 new file mode 100644 index 0000000000..5454e4d7ba --- /dev/null +++ b/tests/bugs/vis/bug31673 @@ -0,0 +1,22 @@ +puts "============" +puts "0031673: Draw Harness, ViewerTest - vlocation -rotate is applied in opposite order" +puts "============" +puts "" + +pload MODELING VISUALIZATION +box b -1 -1 -1 2 2 2 +explode b F +vclear +vinit View1 +vdisplay -dispMode 0 b_1 b_3 b_4 b_6 +vdisplay -dispMode 1 b_2 b_5 +vfit +vzoom 0.4 +vlocation b_2 -reset +vlocation b_5 -reset +vlocation b_2 -rotate 1 -1 -1 0 1 0 90 +vlocation b_2 -rotate -1 -1 -1 0 1 0 90 +vlocation b_5 -rotate -1 -1 -1 0 1 0 90 +if { [vreadpixel 170 380 -rgb -name] == "BLACK" } { puts "Error: wrong rotation" } + +vdump ${imagedir}/${casename}.png diff --git a/tests/v3d/glsl/bndbox1 b/tests/v3d/glsl/bndbox1 index 61b8552299..67c36732ba 100644 --- a/tests/v3d/glsl/bndbox1 +++ b/tests/v3d/glsl/bndbox1 @@ -10,7 +10,7 @@ vaxo psphere s0 1 psphere s1 1 vdisplay -dispMode 1 s0 s1 -vlocation s1 -reset -translate 2 1 0 -rotate 0 0 0 1 0 0 20 +vlocation s1 -reset -rotate 0 0 0 1 0 0 20 -translate 2 1 0 vfit vbounding diff --git a/tests/v3d/raytrace/bug25221 b/tests/v3d/raytrace/bug25221 index 468a3663ce..08e8673b46 100644 --- a/tests/v3d/raytrace/bug25221 +++ b/tests/v3d/raytrace/bug25221 @@ -43,8 +43,7 @@ vmoveto 200 200 vdump $imagedir/${casename}_faces_closeup.png # apply transformation -vlocation s -rotate 0 0 0 0 0 1 10 -vlocation s -translate -30 0 0 +vlocation s -reset -translate -30 0 0 -rotate 0 0 0 0 0 1 10 vmoveto 0 0 vmoveto 200 200