ReCompute();
}
- GraphicTransform (aNewTrsf);
+ myCStructure->UpdateTransformation();
myStructureManager->SetTransform (this, aNewTrsf);
Update();
myGlVerMinor (0),
myIsInitialized (Standard_False),
myIsStereoBuffers (Standard_False),
+ myIsGlNormalizeEnabled (Standard_False),
#if !defined(GL_ES_VERSION_2_0)
myRenderMode (GL_RENDER),
#else
}
#endif
}
+
+// =======================================================================
+// function : SetGlNormalizeEnabled
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
+{
+ if (isEnabled == myIsGlNormalizeEnabled)
+ {
+ return myIsGlNormalizeEnabled;
+ }
+
+ Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
+
+ myIsGlNormalizeEnabled = isEnabled;
+
+#if !defined(GL_ES_VERSION_2_0)
+ if (isEnabled)
+ {
+ glEnable (GL_NORMALIZE);
+ }
+ else
+ {
+ glDisable (GL_NORMALIZE);
+ }
+#endif
+
+ return anOldGlNormalize;
+}
&& !caps->vboDisable;
}
+ //! @return cached state of GL_NORMALIZE.
+ Standard_Boolean IsGlNormalizeEnabled() const { return myIsGlNormalizeEnabled; }
+
+ //! Sets GL_NORMALIZE enabled or disabled.
+ //! @return old value of the flag
+ Standard_EXPORT Standard_Boolean SetGlNormalizeEnabled (Standard_Boolean isEnabled);
+
public:
//! @return messenger instance
OpenGl_Clipping myClippingState; //!< state of clip planes
- void* myGlLibHandle; //!< optional handle to GL library
+ void* myGlLibHandle; //!< optional handle to GL library
NCollection_Handle<OpenGl_GlFunctions>
- myFuncs; //!< mega structure for all GL functions
- Standard_Integer myAnisoMax; //!< maximum level of anisotropy texture filter
- Standard_Integer myTexClamp; //!< either GL_CLAMP_TO_EDGE (1.2+) or GL_CLAMP (1.1)
- Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE
- Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES
- Standard_Integer myGlVerMajor; //!< cached GL version major number
- Standard_Integer myGlVerMinor; //!< cached GL version minor number
- Standard_Boolean myIsInitialized; //!< flag indicates initialization state
- Standard_Boolean myIsStereoBuffers; //!< context supports stereo buffering
+ myFuncs; //!< mega structure for all GL functions
+ Standard_Integer myAnisoMax; //!< maximum level of anisotropy texture filter
+ Standard_Integer myTexClamp; //!< either GL_CLAMP_TO_EDGE (1.2+) or GL_CLAMP (1.1)
+ Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE
+ Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES
+ Standard_Integer myGlVerMajor; //!< cached GL version major number
+ Standard_Integer myGlVerMinor; //!< cached GL version minor number
+ Standard_Boolean myIsInitialized; //!< flag indicates initialization state
+ Standard_Boolean myIsStereoBuffers; //!< context supports stereo buffering
+ Standard_Boolean myIsGlNormalizeEnabled; //!< GL_NORMALIZE flag
+ //!< Used to tell OpenGl that normals should be normalized
Handle(OpenGl_ShaderManager) myShaderManager; //! support object for managing shader programs
myZLayer(0),
myIsRaytracable (Standard_False),
myModificationState (0),
- myIsCulled (Standard_True)
+ myIsCulled (Standard_True),
+ myIsMirrored (Standard_False)
{
UpdateNamedStatus();
}
myTransformation = new OpenGl_Matrix();
}
+ Standard_ShortReal (*aMat)[4] = Graphic3d_CStructure::Transformation;
+
+ Standard_ShortReal aDet =
+ aMat[0][0] * (aMat[1][1] * aMat[2][2] - aMat[2][1] * aMat[1][2]) -
+ aMat[0][1] * (aMat[1][0] * aMat[2][2] - aMat[2][0] * aMat[1][2]) +
+ aMat[0][2] * (aMat[1][0] * aMat[2][1] - aMat[2][0] * aMat[1][1]);
+
+ // Determinant of transform matrix less then 0 means that mirror transform applied.
+ myIsMirrored = aDet < 0.0f;
+
matcpy (myTransformation->mat, &Graphic3d_CStructure::Transformation[0][0]);
if (myIsRaytracable)
void OpenGl_Structure::HighlightWithColor (const Graphic3d_Vec3& theColor,
const Standard_Boolean theToCreate)
{
- const Handle(OpenGl_Context)& aCtx = GlDriver()->GetSharedContext();
+ const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
if (theToCreate)
- setHighlightColor (aCtx, theColor);
+ setHighlightColor (aContext, theColor);
else
- clearHighlightColor (aCtx);
+ clearHighlightColor (aContext);
}
// =======================================================================
void OpenGl_Structure::HighlightWithBndBox (const Handle(Graphic3d_Structure)& theStruct,
const Standard_Boolean theToCreate)
{
- const Handle(OpenGl_Context)& aCtx = GlDriver()->GetSharedContext();
+ const Handle(OpenGl_Context)& aContext = GlDriver()->GetSharedContext();
if (!theToCreate)
{
- clearHighlightBox (aCtx);
+ clearHighlightBox (aContext);
return;
}
if (!myHighlightBox.IsNull())
{
- myHighlightBox->Release (aCtx);
+ myHighlightBox->Release (aContext);
}
else
{
// function : RenderGeometry
// purpose :
// =======================================================================
-void OpenGl_Structure::RenderGeometry (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_Structure::RenderGeometry (const Handle(OpenGl_Workspace) &theWorkspace) const
{
// Render groups
const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
{
- aGroupIter.Value()->Render (AWorkspace);
+ aGroupIter.Value()->Render (theWorkspace);
}
}
// function : Render
// purpose :
// =======================================================================
-void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
{
// Process the structure only if visible
- if ( myNamedStatus & OPENGL_NS_HIDE )
+ if (myNamedStatus & OPENGL_NS_HIDE)
+ {
return;
+ }
- const Handle(OpenGl_Context)& aCtx = AWorkspace->GetGlContext();
+ const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
// Render named status
- const Standard_Integer named_status = AWorkspace->NamedStatus;
- AWorkspace->NamedStatus |= myNamedStatus;
+ const Standard_Integer aNamedStatus = theWorkspace->NamedStatus;
+ theWorkspace->NamedStatus |= myNamedStatus;
// Is rendering in ADD or IMMEDIATE mode?
- const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0;
+ const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & OPENGL_NS_IMMEDIATE) != 0;
+
+ // Do we need to restore GL_NORMALIZE?
+ Standard_Boolean anOldGlNormalize = aContext->IsGlNormalizeEnabled();
// Apply local transformation
- GLint matrix_mode = 0;
- const OpenGl_Matrix *local_trsf = NULL;
+ GLint aMatrixMode = 0;
+ const OpenGl_Matrix* aLocalTrsf = NULL;
if (myTransformation)
{
#if !defined(GL_ES_VERSION_2_0)
+
+ Standard_ShortReal aScaleX = OpenGl_Vec3 (myTransformation->mat[0][0],
+ myTransformation->mat[0][1],
+ myTransformation->mat[0][2]).SquareModulus();
+ // Scale transform detected.
+ if (Abs (aScaleX - 1.f) > Precision::Confusion())
+ {
+ anOldGlNormalize = aContext->SetGlNormalizeEnabled (Standard_True);
+ }
+
if (isImmediate)
{
Tmatrix3 aModelWorld;
call_util_transpose_mat (*aModelWorld, myTransformation->mat);
- glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
+ glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
- if (!aCtx->ShaderManager()->IsEmpty())
+ if (!aContext->ShaderManager()->IsEmpty())
{
Tmatrix3 aWorldView;
glGetFloatv (GL_MODELVIEW_MATRIX, *aWorldView);
Tmatrix3 aProjection;
glGetFloatv (GL_PROJECTION_MATRIX, *aProjection);
- aCtx->ShaderManager()->UpdateModelWorldStateTo (&aModelWorld);
- aCtx->ShaderManager()->UpdateWorldViewStateTo (&aWorldView);
- aCtx->ShaderManager()->UpdateProjectionStateTo (&aProjection);
+ aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorld);
+ aContext->ShaderManager()->UpdateWorldViewStateTo (&aWorldView);
+ aContext->ShaderManager()->UpdateProjectionStateTo (&aProjection);
}
glMatrixMode (GL_MODELVIEW);
glPushMatrix ();
- glScalef (1.F, 1.F, 1.F);
+ glScalef (1.0f, 1.0f, 1.0f);
glMultMatrixf (*aModelWorld);
}
else
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
- local_trsf = AWorkspace->SetStructureMatrix (myTransformation);
+ aLocalTrsf = theWorkspace->SetStructureMatrix (myTransformation);
}
#endif
}
// Apply transform persistence
- const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
+ const TEL_TRANSFORM_PERSISTENCE *aTransPersistence = NULL;
if ( myTransPers && myTransPers->mode != 0 )
{
- trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence (aCtx, myTransPers);
+ aTransPersistence = theWorkspace->ActiveView()->BeginTransformPersistence (aContext, myTransPers);
}
// Apply aspects
- const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
- const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
- const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
- const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
+ const OpenGl_AspectLine *anAspectLine = theWorkspace->AspectLine (Standard_False);
+ const OpenGl_AspectFace *anAspectFace = theWorkspace->AspectFace (Standard_False);
+ const OpenGl_AspectMarker *anAspectMarker = theWorkspace->AspectMarker (Standard_False);
+ const OpenGl_AspectText *anAspectText = theWorkspace->AspectText (Standard_False);
if (myAspectLine)
- AWorkspace->SetAspectLine(myAspectLine);
+ {
+ theWorkspace->SetAspectLine (myAspectLine);
+ }
if (myAspectFace)
- AWorkspace->SetAspectFace(myAspectFace);
+ {
+ theWorkspace->SetAspectFace (myAspectFace);
+ }
if (myAspectMarker)
- AWorkspace->SetAspectMarker(myAspectMarker);
+ {
+ theWorkspace->SetAspectMarker (myAspectMarker);
+ }
if (myAspectText)
- AWorkspace->SetAspectText(myAspectText);
+ {
+ theWorkspace->SetAspectText (myAspectText);
+ }
+
+ // Apply correction for mirror transform
+ if (myIsMirrored)
+ {
+ glFrontFace (GL_CW);
+ }
// Apply highlight color
- const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
+ const TEL_COLOUR *aHighlightColor = theWorkspace->HighlightColor;
if (myHighlightColor)
- AWorkspace->HighlightColor = myHighlightColor;
+ theWorkspace->HighlightColor = myHighlightColor;
// Render connected structures
- OpenGl_ListOfStructure::Iterator its(myConnected);
- while (its.More())
+ OpenGl_ListOfStructure::Iterator anIter (myConnected);
+ while (anIter.More())
{
- its.Value()->RenderGeometry (AWorkspace);
- its.Next();
+ anIter.Value()->RenderGeometry (theWorkspace);
+ anIter.Next();
}
// Set up plane equations for non-structure transformed global model-view matrix
- const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
-
// List of planes to be applied to context state
Handle(Graphic3d_SequenceOfHClipPlane) aUserPlanes;
// Collect clipping planes of structure scope
if (!myClipPlanes.IsEmpty())
{
- Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
- for (; aClippingIt.More(); aClippingIt.Next())
+ Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes);
+ for (; aClippingIter.More(); aClippingIter.Next())
{
- const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
+ const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value();
if (!aClipPlane->IsOn())
{
continue;
if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
{
// add planes at loaded view matrix state
- aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
+ aContext->ChangeClipping().AddWorld (*aUserPlanes, theWorkspace);
// Set OCCT state uniform variables
if (!aContext->ShaderManager()->IsEmpty())
const Graphic3d_SequenceOfGroup& aGroups = DrawGroups();
for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next())
{
- aGroupIter.Value()->Render (AWorkspace);
+ aGroupIter.Value()->Render (theWorkspace);
}
+ // Reset correction for mirror transform
+ if (myIsMirrored)
+ glFrontFace (GL_CCW); // default
+
// Render capping for structure groups
if (!aContext->Clipping().Planes().IsEmpty())
{
- OpenGl_CappingAlgo::RenderCapping (AWorkspace, aGroups);
+ OpenGl_CappingAlgo::RenderCapping (theWorkspace, aGroups);
}
// Revert structure clippings
}
// Restore highlight color
- AWorkspace->HighlightColor = highlight_color;
+ theWorkspace->HighlightColor = aHighlightColor;
// Restore aspects
- AWorkspace->SetAspectLine(aspect_line);
- AWorkspace->SetAspectFace(aspect_face);
- AWorkspace->SetAspectMarker(aspect_marker);
- AWorkspace->SetAspectText(aspect_text);
+ theWorkspace->SetAspectLine (anAspectLine);
+ theWorkspace->SetAspectFace (anAspectFace);
+ theWorkspace->SetAspectMarker (anAspectMarker);
+ theWorkspace->SetAspectText (anAspectText);
// Restore transform persistence
if ( myTransPers && myTransPers->mode != 0 )
{
- AWorkspace->ActiveView()->BeginTransformPersistence (aContext, trans_pers);
+ theWorkspace->ActiveView()->BeginTransformPersistence (aContext, aTransPersistence);
}
// Restore local transformation
if (myTransformation)
{
#if !defined(GL_ES_VERSION_2_0)
+
+ aContext->SetGlNormalizeEnabled (anOldGlNormalize);
+
if (isImmediate)
{
glPopMatrix ();
- glMatrixMode (matrix_mode);
+ glMatrixMode (aMatrixMode);
Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
{ 0.f, 1.f, 0.f, 0.f },
}
else
{
- AWorkspace->SetStructureMatrix (local_trsf, true);
+ theWorkspace->SetStructureMatrix (aLocalTrsf, true);
glMatrixMode (GL_MODELVIEW);
glPopMatrix();
// Apply highlight box
if (!myHighlightBox.IsNull())
{
- myHighlightBox->Render (AWorkspace);
+ myHighlightBox->Render (theWorkspace);
}
// Restore named status
- AWorkspace->NamedStatus = named_status;
+ theWorkspace->NamedStatus = aNamedStatus;
}
// =======================================================================
mutable Standard_Boolean myIsCulled; //!< A status specifying is structure needs to be rendered after BVH tree traverse.
+ Standard_Boolean myIsMirrored; //!< Used to tell OpenGl to interpret polygons in clockwise order.
+
public:
DEFINE_STANDARD_RTTI(OpenGl_Structure) // Type definition
// if the view is scaled normal vectors are scaled to unit
// length for correct displaying of shaded objects
const gp_Pnt anAxialScale = myCamera->AxialScale();
- if(anAxialScale.X() != 1.F ||
- anAxialScale.Y() != 1.F ||
- anAxialScale.Z() != 1.F)
- glEnable(GL_NORMALIZE);
- else if(glIsEnabled(GL_NORMALIZE))
- glDisable(GL_NORMALIZE);
+ if (anAxialScale.X() != 1.F ||
+ anAxialScale.Y() != 1.F ||
+ anAxialScale.Z() != 1.F)
+ {
+ aContext->SetGlNormalizeEnabled (Standard_True);
+ }
+ else
+ {
+ aContext->SetGlNormalizeEnabled (Standard_False);
+ }
// Apply Fog
if ( myFog.IsOn )
continue;
}
const gp_Trsf& aTrsf = aLoc.Transformation();
+
+ // Determinant of transform matrix less then 0 means that mirror transform applied.
+ Standard_Boolean isMirrored = aTrsf.VectorialPart().Determinant() < 0;
+
Poly_Connect aPolyConnect (aT);
// Extracts vertices & normals from nodes
const TColgp_Array1OfPnt& aNodes = aT->Nodes();
if (!aLoc.IsIdentity())
{
aPoint.Transform (aTrsf);
- aNormals (aNodeIter).Transform (aTrsf);
+
+ aNormals (aNodeIter) = aNormals (aNodeIter).Transformed (aTrsf);
}
if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
Standard_Integer anIndex[3];
for (Standard_Integer aTriIter = 1; aTriIter <= aT->NbTriangles(); ++aTriIter)
{
- if (aFace.Orientation() == TopAbs_REVERSED)
+ if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
{
aTriangles (aTriIter).Get (anIndex[0], anIndex[2], anIndex[1]);
}
return 0;
}
+//=======================================================================
+//function : TransformPresentation
+//purpose : Change transformation of AIS interactive object
+//=======================================================================
+static Standard_Integer LocalTransformPresentation (Draw_Interpretor& /*theDi*/,
+ Standard_Integer theArgNb,
+ const char** theArgVec)
+{
+ if (theArgNb <= 1)
+ {
+ std::cout << "Error: too few arguments.\n";
+ return 1;
+ }
+
+ Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
+ ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
+ if (aContext.IsNull())
+ {
+ std::cout << "Error: no active view!\n";
+ return 1;
+ }
+
+ gp_Trsf aTrsf;
+ Standard_Integer aLast = theArgNb;
+ const char* aName = theArgVec[0];
+
+ Standard_Boolean isReset = Standard_False;
+ Standard_Boolean isMove = Standard_False;
+
+ // Prefix 'vloc'
+ aName += 4;
+
+ if (!strcmp (aName, "reset"))
+ {
+ isReset = Standard_True;
+ }
+ else if (!strcmp (aName, "move"))
+ {
+ if (theArgNb < 3)
+ {
+ std::cout << "Error: too few arguments.\n";
+ return 1;
+ }
+
+ const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
+
+ Handle(AIS_InteractiveObject) anIObj;
+ if (aMap.IsBound2 (theArgVec[theArgNb - 1]))
+ {
+ anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[theArgNb - 1]));
+ }
+
+ if (anIObj.IsNull())
+ {
+ std::cout << "Error: object '" << theArgVec[theArgNb - 1] << "' is not displayed!\n";
+ return 1;
+ }
+
+ isMove = Standard_True;
+
+ aTrsf = anIObj->Transformation();
+ aLast = theArgNb - 1;
+ }
+ else if (!strcmp (aName, "translate"))
+ {
+ if (theArgNb < 5)
+ {
+ std::cout << "Error: too few arguments.\n";
+ return 1;
+ }
+ aTrsf.SetTranslation (gp_Vec (Draw::Atof (theArgVec[theArgNb - 3]),
+ Draw::Atof (theArgVec[theArgNb - 2]),
+ Draw::Atof (theArgVec[theArgNb - 1])));
+ aLast = theArgNb - 3;
+ }
+ else if (!strcmp (aName, "rotate"))
+ {
+ if (theArgNb < 9)
+ {
+ std::cout << "Error: too few arguments.\n";
+ return 1;
+ }
+
+ aTrsf.SetRotation (
+ gp_Ax1 (gp_Pnt (Draw::Atof (theArgVec[theArgNb - 7]),
+ Draw::Atof (theArgVec[theArgNb - 6]),
+ Draw::Atof (theArgVec[theArgNb - 5])),
+ gp_Vec (Draw::Atof (theArgVec[theArgNb - 4]),
+ Draw::Atof (theArgVec[theArgNb - 3]),
+ Draw::Atof (theArgVec[theArgNb - 2]))),
+ Draw::Atof (theArgVec[theArgNb - 1]) * (M_PI / 180.0));
+
+ aLast = theArgNb - 7;
+ }
+ else if (!strcmp (aName, "mirror"))
+ {
+ if (theArgNb < 8)
+ {
+ std::cout << "Error: too few arguments.\n";
+ return 1;
+ }
+
+ aTrsf.SetMirror (gp_Ax2 (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 6]),
+ Draw::Atof(theArgVec[theArgNb - 5]),
+ Draw::Atof(theArgVec[theArgNb - 4])),
+ gp_Vec (Draw::Atof(theArgVec[theArgNb - 3]),
+ Draw::Atof(theArgVec[theArgNb - 2]),
+ Draw::Atof(theArgVec[theArgNb - 1]))));
+ aLast = theArgNb - 6;
+ }
+ else if (!strcmp (aName, "scale"))
+ {
+ if (theArgNb < 6)
+ {
+ std::cout << "Error: too few arguments.\n";
+ return 1;
+ }
+
+ aTrsf.SetScale (gp_Pnt (Draw::Atof(theArgVec[theArgNb - 4]),
+ Draw::Atof(theArgVec[theArgNb - 3]),
+ Draw::Atof(theArgVec[theArgNb - 2])),
+ Draw::Atof(theArgVec[theArgNb - 1]));
+ aLast = theArgNb - 4;
+ }
+
+ for (Standard_Integer anIdx = 1; anIdx < aLast; anIdx++)
+ {
+ // find object
+ const ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
+ Handle(AIS_InteractiveObject) anIObj;
+ if (aMap.IsBound2 (theArgVec[anIdx]))
+ {
+ anIObj = Handle(AIS_InteractiveObject)::DownCast (aMap.Find2 (theArgVec[anIdx]));
+ }
+ if (anIObj.IsNull())
+ {
+ std::cout << "Error: object '" << theArgVec[anIdx] << "' is not displayed!\n";
+ return 1;
+ }
+
+ if (isReset)
+ {
+ // aTrsf already identity
+ }
+ else if (isMove)
+ {
+ aTrsf = anIObj->LocalTransformation() * anIObj->Transformation().Inverted() * aTrsf;
+ }
+ else
+ {
+ aTrsf = anIObj->LocalTransformation() * aTrsf;
+ }
+
+ TopLoc_Location aLocation (aTrsf);
+ aContext->SetLocation (anIObj, aLocation);
+ }
+
+ return 0;
+}
+
//===============================================================================================
//function : VConnect
//purpose : Creates and displays AIS_ConnectedInteractive object from input object and location
"\n\t\t: -noNormals - do not generate normal per point"
"\n",
__FILE__, VPointCloud, group);
+
+ theCommands.Add("vlocreset",
+ "vlocreset name1 name2 ...\n\t\t remove object local transformation",
+ __FILE__,
+ LocalTransformPresentation, group);
+
+ theCommands.Add("vlocmove",
+ "vlocmove name1 name2 ... name\n\t\t set local transform to match transform of 'name'",
+ __FILE__,
+ LocalTransformPresentation, group);
+
+ theCommands.Add("vloctranslate",
+ "vloctranslate name1 name2 ... dx dy dz\n\t\t applies translation to local transformation",
+ __FILE__,
+ LocalTransformPresentation, group);
+
+ theCommands.Add("vlocrotate",
+ "vlocrotate name1 name2 ... x y z dx dy dz angle\n\t\t applies rotation to local transformation",
+ __FILE__,
+ LocalTransformPresentation, group);
+
+ theCommands.Add("vlocmirror",
+ "vlocmirror name x y z dx dy dz\n\t\t applies mirror to local transformation",
+ __FILE__,
+ LocalTransformPresentation, group);
+
+ theCommands.Add("vlocscale",
+ "vlocscale name x y z scale\n\t\t applies scale to local transformation",
+ __FILE__,
+ LocalTransformPresentation, group);
}
--- /dev/null
+puts "============"
+puts "OCC25276"
+puts "============"
+puts ""
+#######################################################################
+# Visualization - Lighting is broken if some kinds of transformation applied to a shape
+#######################################################################
+
+pload ALL
+vinit
+box b1 1 6 1
+vsetdispmode 1
+vdisplay b1
+vconnectto b2 6 0 0 b1
+box b3 7 1 1
+vdisplay b3
+vloctranslate b3 0 4 0
+vconnect z 0 0 0 b1 b2 b3
+
+vconnect z1 0 0 0 z
+vloctranslate z1 10 0 0
+
+vconnect z2 0 10 0 z
+vlocrotate z2 0 0 0 1 0 0 90
+
+vconnect z3 -10 0 0 z
+vlocscale z3 0 0 0 0.5
+
+vconnect z4 0 0 0 z
+vlocmove z4 z3
+
+psphere sp 3
+vdisplay sp
+vlocmove sp z3
+vlocreset sp
+
+vlocmirror z 0 -0.5 0 0 1 0
+vfit
+
+vdump $imagedir/${casename}.png