From 992ed6b3c05f5fa60edfde74d4bb6c49daa27574 Mon Sep 17 00:00:00 2001 From: kgv Date: Thu, 2 Nov 2017 15:36:20 +0300 Subject: [PATCH] 0029290: Visualization, TKOpenGl - allow defining Light source per ZLayer Graphic3d_CLight is now defined as a class inheriting Standard_Transient, so that it's fields now should be accessed through methods. Graphic3d_CLight::IsEnabled() - new property allowing to disable light source everywhere. Confusing alias OpenGl_Light has been removed. Graphic3d_CLight::SetAttenuation() - the upper limit 1.0 of attenuation factors has been removed since it contradicts to OpenGL specs and does not make sense. Graphic3d_ZLayerSettings::Lights() - light sources list is now property of ZLayer. When defined, it overrides light sources defined for View/Viewer. New class Graphic3d_LightSet has been defined to define a set of light sources. V3d_Light - removed obsolete interface for debug drawing lights sources. V3d_Light is now an alias to Graphic3d_CLight. V3d_TypeOfLight is now defined as a typedef to Graphic3d_TypeOfLightSource. --- dox/dev_guides/upgrade/upgrade.md | 20 +- .../Textures/Textures_Presentation.cpp | 12 +- .../TexturesExt/TexturesExt_Presentation.cpp | 12 +- .../src/TexturesExt_Presentation.cpp | 12 +- .../standard/04_Viewer3d/src/Viewer3dView.cpp | 20 +- samples/tcl/materials.tcl | 3 +- src/Graphic3d/FILES | 3 + src/Graphic3d/Graphic3d_CLight.cxx | 235 +++++++ src/Graphic3d/Graphic3d_CLight.hxx | 247 +++++-- src/Graphic3d/Graphic3d_CView.hxx | 4 +- src/Graphic3d/Graphic3d_LightSet.cxx | 146 +++++ src/Graphic3d/Graphic3d_LightSet.hxx | 190 ++++++ src/Graphic3d/Graphic3d_TypeOfLightSource.hxx | 26 +- .../Graphic3d_TypeOfShadingModel.hxx | 6 + src/Graphic3d/Graphic3d_ZLayerSettings.hxx | 9 + src/OpenGl/FILES | 1 - src/OpenGl/OpenGl_Layer.cxx | 13 + src/OpenGl/OpenGl_LayerList.cxx | 4 + src/OpenGl/OpenGl_Light.hxx | 27 - src/OpenGl/OpenGl_SceneGeometry.cxx | 2 +- src/OpenGl/OpenGl_ShaderManager.cxx | 278 ++++---- src/OpenGl/OpenGl_ShaderManager.hxx | 2 +- src/OpenGl/OpenGl_ShaderStates.cxx | 28 - src/OpenGl/OpenGl_ShaderStates.hxx | 10 +- src/OpenGl/OpenGl_View.cxx | 15 +- src/OpenGl/OpenGl_View.hxx | 13 +- src/OpenGl/OpenGl_View_Raytrace.cxx | 93 ++- src/OpenGl/OpenGl_View_Redraw.cxx | 14 +- src/StdPrs/StdPrs_Plane.cxx | 1 - src/V3d/FILES | 1 - src/V3d/V3d.cxx | 11 +- src/V3d/V3d.hxx | 5 +- src/V3d/V3d_AmbientLight.cxx | 23 +- src/V3d/V3d_AmbientLight.hxx | 36 +- src/V3d/V3d_DirectionalLight.cxx | 273 +------- src/V3d/V3d_DirectionalLight.hxx | 97 +-- src/V3d/V3d_Light.cxx | 188 ------ src/V3d/V3d_Light.hxx | 77 +-- src/V3d/V3d_ListOfLight.hxx | 6 +- src/V3d/V3d_PositionLight.cxx | 416 +----------- src/V3d/V3d_PositionLight.hxx | 89 +-- src/V3d/V3d_PositionalLight.cxx | 262 +------- src/V3d/V3d_PositionalLight.hxx | 120 +--- src/V3d/V3d_SpotLight.cxx | 246 ++----- src/V3d/V3d_SpotLight.hxx | 148 +---- src/V3d/V3d_TypeOfLight.hxx | 11 +- src/V3d/V3d_View.cxx | 4 +- src/V3d/V3d_View.hxx | 1 - src/V3d/V3d_Viewer.cxx | 8 +- src/V3d/V3d_Viewer.hxx | 10 +- src/ViewerTest/ViewerTest_ViewerCommands.cxx | 604 ++++++++++-------- tests/v3d/glsl/phong_pos1 | 5 +- tests/v3d/glsl/phong_pos3 | 46 ++ tests/v3d/glsl/phong_pos4 | 35 + tests/v3d/materials/bug24855 | 2 +- tests/v3d/raytrace/bug24130 | 2 +- tests/v3d/raytrace/bug24819 | 2 +- tests/v3d/raytrace/bug25201 | 2 +- tests/v3d/raytrace/bug26617 | 2 +- tests/v3d/raytrace/refraction | 2 +- tests/v3d/raytrace/textures | 2 +- 61 files changed, 1816 insertions(+), 2366 deletions(-) create mode 100644 src/Graphic3d/Graphic3d_CLight.cxx create mode 100644 src/Graphic3d/Graphic3d_LightSet.cxx create mode 100644 src/Graphic3d/Graphic3d_LightSet.hxx delete mode 100644 src/OpenGl/OpenGl_Light.hxx delete mode 100644 src/V3d/V3d_Light.cxx create mode 100644 tests/v3d/glsl/phong_pos3 create mode 100644 tests/v3d/glsl/phong_pos4 diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md index 1909ee2191..7a3d447de3 100644 --- a/dox/dev_guides/upgrade/upgrade.md +++ b/dox/dev_guides/upgrade/upgrade.md @@ -1501,4 +1501,22 @@ The following obsolete features have been removed: - *IntTools_IndexedDataMapOfTransientAddress* is removed as unused; * The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*; * The class *BOPTools* has been removed as duplicate of the class *TopExp*; -* The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead. \ No newline at end of file +* The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead. + +@section upgrade_occt730 Upgrade to OCCT 7.3.0 + +@subsection upgrade_730_lights Light sources + +Multiple changes have been applied to lights management within TKV3d and TKOpenGl: +* V3d_Light class is now an alias to Graphic3d_CLight. + Graphic3d_CLight is now a Handle class with refactored methods for managing light source parameters + (preserving most methods of V3d_Light sub-classes to simplify porting). +* Obsolete debugging functionality for drawing lights source has been removed from V3d_Light. + Methods and constructors taking parameters for this drawing and not affecting light definition itself has been also removed. +* Light constructors taking V3d_Viewer has been marked deprecated. + Application may call V3d_Viewer::AddLight() explicitly to register new light sources created by new constructors within V3d_Viewer, but this step is now optional. +* The upper limit of 8 light sources has been removed. +* Dedicated classes per light source type V3d_AmbientLight, V3d_DirectionalLight, V3d_PositionalLight and V3d_SpotLight have been preserved, + but it is now possible defining light of any type by creating base class Graphic3d_CLight directly. + Dedicated classes only hides visibility of unrelated light properties depending on its type. +* Calling V3d_Viewer::UpdateLights() is no more required after modifying light sources properties (color, position, etc.). diff --git a/samples/mfc/occtdemo/Textures/Textures_Presentation.cpp b/samples/mfc/occtdemo/Textures/Textures_Presentation.cpp index cf5b1e65b6..68e449767d 100755 --- a/samples/mfc/occtdemo/Textures/Textures_Presentation.cpp +++ b/samples/mfc/occtdemo/Textures/Textures_Presentation.cpp @@ -137,12 +137,12 @@ void Textures_Presentation::Init() //================================================================ void Textures_Presentation::lightsOnOff(Standard_Boolean isOn) { - static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZneg); - static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZpos); - static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(getViewer(), V3d_XposYnegZpos); - static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZneg); - static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZpos); - static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(getViewer(), V3d_XposYposZpos); + static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg); + static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos); + static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos); + static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg); + static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos); + static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos); if (isOn) { diff --git a/samples/mfc/occtdemo/TexturesExt/TexturesExt_Presentation.cpp b/samples/mfc/occtdemo/TexturesExt/TexturesExt_Presentation.cpp index 1a548b53d9..07ac0bb53f 100755 --- a/samples/mfc/occtdemo/TexturesExt/TexturesExt_Presentation.cpp +++ b/samples/mfc/occtdemo/TexturesExt/TexturesExt_Presentation.cpp @@ -185,12 +185,12 @@ Standard_Boolean TexturesExt_Presentation::loadShape(TopoDS_Shape& aShape, //================================================================ void TexturesExt_Presentation::lightsOnOff(Standard_Boolean isOn) { - static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZneg); - static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZpos); - static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(getViewer(), V3d_XposYnegZpos); - static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZneg); - static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZpos); - static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(getViewer(), V3d_XposYposZpos); + static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg); + static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos); + static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos); + static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg); + static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos); + static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos); if (isOn) { diff --git a/samples/mfc/standard/04_Viewer3d/src/TexturesExt_Presentation.cpp b/samples/mfc/standard/04_Viewer3d/src/TexturesExt_Presentation.cpp index 902a50410a..b542673eec 100755 --- a/samples/mfc/standard/04_Viewer3d/src/TexturesExt_Presentation.cpp +++ b/samples/mfc/standard/04_Viewer3d/src/TexturesExt_Presentation.cpp @@ -191,12 +191,12 @@ Standard_Boolean TexturesExt_Presentation::loadShape(TopoDS_Shape& aShape, //================================================================ void TexturesExt_Presentation::lightsOnOff(Standard_Boolean isOn) { - static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZneg); - static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZpos); - static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(getViewer(), V3d_XposYnegZpos); - static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZneg); - static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZpos); - static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(getViewer(), V3d_XposYposZpos); + static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg); + static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos); + static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos); + static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg); + static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos); + static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos); if (isOn) { diff --git a/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp b/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp index 9be1e1a001..01da072c97 100755 --- a/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp +++ b/samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp @@ -416,7 +416,7 @@ GetDocument()->UpdateResultMessageDlg("SetPosition",Message); case CurAction3d_BeginSpotLight : { p1 = ConvertClickToPoint(point.x,point.y,myView); - myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(),0.,0.,1., p1.X(),p1.Y(),p1.Z(),Quantity_NOC_RED); + myCurrent_SpotLight = new V3d_SpotLight (p1, gp_Dir (gp_XYZ (0.0, 0.0, 1.0) - p1.XYZ()), Quantity_NOC_RED); myView->SetLightOn(myCurrent_SpotLight); NbActiveLights++; p2 = gp_Pnt(p1.X(),p1.Y(),p1.Z()+1.); @@ -461,7 +461,7 @@ GetDocument()->UpdateResultMessageDlg("SetAngle",Message); directionalEdgeShape->Set(MakeEdge.Edge()); GetDocument()->GetAISContext()->Display (directionalEdgeShape, 0, -1, Standard_True); // Create a directional light - myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), p1.X(),p1.Y(),p1.Z(),0.,0.,1.); + myCurrent_DirectionalLight = new V3d_DirectionalLight (gp_Dir (p1.XYZ() - gp_XYZ (0.,0.,1.))); myView->SetLightOn(myCurrent_DirectionalLight); NbActiveLights++; ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the target point"); @@ -745,7 +745,7 @@ void CViewer3dView::OnMouseMove(UINT nFlags, CPoint point) 0, p2.Distance(p3), coneHeigth); spotConeShape->Set(MakeCone.Solid()); GetDocument()->GetAISContext()->Redisplay(spotConeShape,0,Standard_True); - myCurrent_SpotLight->SetAngle(atan(p2.Distance(p3)/p1.Distance(p2))) ; + myCurrent_SpotLight->SetAngle((float )atan(p2.Distance(p3)/p1.Distance(p2))) ; myView->UpdateLights(); } } @@ -894,7 +894,7 @@ void CViewer3dView::OnDirectionalLight() myCurrentMode = CurAction3d_BeginDirectionalLight; TCollection_AsciiString Message("\ -myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp);\n\ +myCurrent_DirectionalLight = new V3d_DirectionalLight (gp_Dir (theDirection));\n\ \n\ myView->SetLightOn(myCurrent_DirectionalLight);\n\ \n\ @@ -920,7 +920,7 @@ void CViewer3dView::OnSpotLight() myCurrentMode = CurAction3d_BeginSpotLight; TCollection_AsciiString Message("\ -myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp,Quantity_NOC_RED);\n\ +myCurrent_SpotLight = new V3d_SpotLight (gp_Pnt (thePosition), gp_Dir (theDirection), Quantity_NOC_RED);\n\ \n\ myView->SetLightOn(myCurrent_SpotLight);\n\ \n\ @@ -942,14 +942,16 @@ void CViewer3dView::OnPositionalLight() return; } - myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),0,0,0,Quantity_NOC_GREEN,1,0); + myCurrent_PositionalLight=new V3d_PositionalLight (gp_Pnt (0,0,0), Quantity_NOC_GREEN); + myCurrent_PositionalLight->SetAttenuation (1, 0); myView->SetLightOn(myCurrent_PositionalLight); NbActiveLights++; ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the light position"); myCurrentMode = CurAction3d_BeginPositionalLight; TCollection_AsciiString Message("\ -myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),Xp, Yp, Zp,Quantity_NOC_GREEN,1,0);\n\ +myCurrent_PositionalLight=new V3d_PositionalLight (gp_Pnt(thePosition),Quantity_NOC_GREEN);\n\ +myCurrent_PositionalLight->SetAttenuation (1, 0);\n\ \n\ myView->SetLightOn(myCurrent_PositionalLight) ;\n\ "); @@ -971,14 +973,14 @@ void CViewer3dView::OnAmbientLight() return; } - myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY); + myCurrent_AmbientLight=new V3d_AmbientLight (Quantity_NOC_GRAY); myView->SetLightOn(myCurrent_AmbientLight) ; NbActiveLights++; myView->UpdateLights(); TCollection_AsciiString Message("\ -myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);\n\ +myCurrent_AmbientLight=new V3d_AmbientLight(Quantity_NOC_GRAY);\n\ \n\ myView->SetLightOn(myCurrent_AmbientLight) ;\n\ "); diff --git a/samples/tcl/materials.tcl b/samples/tcl/materials.tcl index ba40779800..cfef461004 100644 --- a/samples/tcl/materials.tcl +++ b/samples/tcl/materials.tcl @@ -70,7 +70,8 @@ vclear vtop vglinfo vsetgradientbg 180 200 255 180 180 180 2 -vlight change 0 pos -1 1 1 + +vlight -change 0 -dir 0.577 -0.577 -0.577 vsetdispmode 1 vrenderparams -msaa 8 diff --git a/src/Graphic3d/FILES b/src/Graphic3d/FILES index 42151dd00e..3f7ab9fbf3 100755 --- a/src/Graphic3d/FILES +++ b/src/Graphic3d/FILES @@ -30,6 +30,7 @@ Graphic3d_Camera.cxx Graphic3d_Camera.hxx Graphic3d_CameraTile.hxx Graphic3d_CappingFlags.hxx +Graphic3d_CLight.cxx Graphic3d_CLight.hxx Graphic3d_ClipPlane.cxx Graphic3d_ClipPlane.hxx @@ -58,6 +59,8 @@ Graphic3d_HorizontalTextAlignment.hxx Graphic3d_IndexBuffer.hxx Graphic3d_IndexedMapOfAddress.hxx Graphic3d_LevelOfTextureAnisotropy.hxx +Graphic3d_LightSet.cxx +Graphic3d_LightSet.hxx Graphic3d_MapIteratorOfMapOfStructure.hxx Graphic3d_MapOfObject.hxx Graphic3d_MapOfStructure.hxx diff --git a/src/Graphic3d/Graphic3d_CLight.cxx b/src/Graphic3d/Graphic3d_CLight.cxx new file mode 100644 index 0000000000..04437873ee --- /dev/null +++ b/src/Graphic3d/Graphic3d_CLight.cxx @@ -0,0 +1,235 @@ +// Copyright (c) 2017 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CLight, Standard_Transient) + +namespace +{ + static volatile Standard_Integer THE_LIGHT_COUNTER = 0; +} + +// ======================================================================= +// function : makeId +// purpose : +// ======================================================================= +void Graphic3d_CLight::makeId() +{ + TCollection_AsciiString aTypeSuffix; + switch (myType) + { + case Graphic3d_TOLS_AMBIENT: aTypeSuffix = "amb"; break; + case Graphic3d_TOLS_DIRECTIONAL: aTypeSuffix = "dir"; break; + case Graphic3d_TOLS_POSITIONAL: aTypeSuffix = "pos"; break; + case Graphic3d_TOLS_SPOT: aTypeSuffix = "spot"; break; + } + + myId = TCollection_AsciiString ("Graphic3d_CLight_") + aTypeSuffix + + TCollection_AsciiString (Standard_Atomic_Increment (&THE_LIGHT_COUNTER)); +} + +// ======================================================================= +// function : Graphic3d_CLight +// purpose : +// ======================================================================= +Graphic3d_CLight::Graphic3d_CLight (Graphic3d_TypeOfLightSource theType) +: myPosition (0.0, 0.0, 0.0), + myColor (1.0f, 1.0f, 1.0f, 1.0f), + myDirection (0.0f, 0.0f, 0.0f, 0.0f), + myParams (0.0f, 0.0f, 0.0f, 0.0f), + mySmoothness (0.0f), + myIntensity (1.0f), + myType (theType), + myRevision (0), + myIsHeadlight(false), + myIsEnabled (true) +{ + switch (theType) + { + case Graphic3d_TOLS_AMBIENT: + { + break; + } + case Graphic3d_TOLS_DIRECTIONAL: + { + mySmoothness = 0.2f; + myIntensity = 20.0f; + break; + } + case Graphic3d_TOLS_POSITIONAL: + { + changeConstAttenuation() = 1.0f; + changeLinearAttenuation() = 0.0f; + break; + } + case Graphic3d_TOLS_SPOT: + { + changeConstAttenuation() = 1.0f; + changeLinearAttenuation() = 0.0f; + changeConcentration() = 1.0f; + changeAngle() = 0.523599f; + break; + } + } + makeId(); +} + +// ======================================================================= +// function : SetColor +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetColor (const Quantity_Color& theColor) +{ + updateRevisionIf (myColor.GetRGB().IsDifferent (theColor)); + myColor.SetRGB (theColor); +} + +// ======================================================================= +// function : SetEnabled +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn) +{ + updateRevisionIf (myIsEnabled != theIsOn); + myIsEnabled = theIsOn; +} + +// ======================================================================= +// function : SetHeadlight +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetHeadlight (Standard_Boolean theValue) +{ + updateRevisionIf (myIsHeadlight != theValue); + myIsHeadlight = theValue; +} + +// ======================================================================= +// function : SetDirection +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetDirection (const gp_Dir& theDir) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT + && myType != Graphic3d_TOLS_DIRECTIONAL, + "Graphic3d_CLight::SetDirection(), incorrect light type"); + updateRevisionIf (Abs (myDirection.x() - static_cast (theDir.X())) > ShortRealEpsilon() + || Abs (myDirection.y() - static_cast (theDir.Y())) > ShortRealEpsilon() + || Abs (myDirection.z() - static_cast (theDir.Z())) > ShortRealEpsilon()); + + myDirection.x() = static_cast (theDir.X()); + myDirection.y() = static_cast (theDir.Y()); + myDirection.z() = static_cast (theDir.Z()); +} + +// ======================================================================= +// function : SetPosition +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetPosition (const gp_Pnt& thePosition) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT + && myType != Graphic3d_TOLS_POSITIONAL, + "Graphic3d_CLight::SetDirection(), incorrect light type"); + updateRevisionIf (!myPosition.IsEqual (thePosition, gp::Resolution())); + myPosition = thePosition; +} + +// ======================================================================= +// function : SetIntensity +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetIntensity (Standard_ShortReal theValue) +{ + Standard_OutOfRange_Raise_if (theValue <= 0.0f, "Graphic3d_CLight::SetIntensity(), Negative value for intensity"); + updateRevisionIf (Abs (myIntensity - theValue) > ShortRealEpsilon()); + myIntensity = theValue; +} + +// ======================================================================= +// function : SetAngle +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetAngle (Standard_ShortReal theAngle) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT, + "Graphic3d_CLight::SetAngle(), incorrect light type"); + Standard_OutOfRange_Raise_if (theAngle <= 0.0 || theAngle >= M_PI, + "Graphic3d_CLight::SetAngle(), bad angle"); + updateRevisionIf (Abs (changeAngle() - theAngle) > ShortRealEpsilon()); + changeAngle() = theAngle; +} + +// ======================================================================= +// function : SetAttenuation +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetAttenuation (Standard_ShortReal theConstAttenuation, + Standard_ShortReal theLinearAttenuation) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_POSITIONAL + && myType != Graphic3d_TOLS_SPOT, + "Graphic3d_CLight::SetAttenuation(), incorrect light type"); + Standard_OutOfRange_Raise_if (theConstAttenuation < 0.0f + || theLinearAttenuation < 0.0f + || theConstAttenuation + theLinearAttenuation == 0.0f, "Graphic3d_CLight::SetAttenuation(), bad coefficient"); + updateRevisionIf (Abs (changeConstAttenuation() - theConstAttenuation) > ShortRealEpsilon() + || Abs (changeLinearAttenuation() - theLinearAttenuation) > ShortRealEpsilon()); + changeConstAttenuation() = theConstAttenuation; + changeLinearAttenuation() = theLinearAttenuation; +} + +// ======================================================================= +// function : SetConcentration +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetConcentration (Standard_ShortReal theConcentration) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT, "Graphic3d_CLight::SetConcentration(), incorrect light type"); + Standard_OutOfRange_Raise_if (theConcentration < 0.0f || theConcentration > 1.0f, + "Graphic3d_CLight::SetConcentration(), bad coefficient"); + updateRevisionIf (Abs (changeConcentration() - theConcentration) > ShortRealEpsilon()); + changeConcentration() = theConcentration; +} + +// ======================================================================= +// function : SetSmoothRadius +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetSmoothRadius (Standard_ShortReal theValue) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_POSITIONAL + && myType != Graphic3d_TOLS_SPOT, + "Graphic3d_CLight::SetSmoothRadius(), incorrect light type"); + Standard_OutOfRange_Raise_if (theValue < 0.0f, "Graphic3d_CLight::SetSmoothRadius(), Bad value for smoothing radius"); + updateRevisionIf (Abs (mySmoothness - theValue) > ShortRealEpsilon()); + mySmoothness = theValue; +} + +// ======================================================================= +// function : SetSmoothAngle +// purpose : +// ======================================================================= +void Graphic3d_CLight::SetSmoothAngle (Standard_ShortReal theValue) +{ + Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_DIRECTIONAL, + "Graphic3d_CLight::SetSmoothAngle(), incorrect light type"); + Standard_OutOfRange_Raise_if (theValue < 0.0f || theValue > Standard_ShortReal(M_PI / 2.0), + "Graphic3d_CLight::SetSmoothAngle(), Bad value for smoothing angle"); + updateRevisionIf (Abs (mySmoothness - theValue) > ShortRealEpsilon()); + mySmoothness = theValue; +} diff --git a/src/Graphic3d/Graphic3d_CLight.hxx b/src/Graphic3d/Graphic3d_CLight.hxx index 8a2283c552..fd8b68c66d 100644 --- a/src/Graphic3d/Graphic3d_CLight.hxx +++ b/src/Graphic3d/Graphic3d_CLight.hxx @@ -14,68 +14,237 @@ #ifndef _Graphic3d_CLight_HeaderFile #define _Graphic3d_CLight_HeaderFile +#include #include #include #include +#include +#include -//! Light definition -struct Graphic3d_CLight +//! Generic light source definition. +//! This class defines arbitrary light source - see Graphic3d_TypeOfLightSource enumeration. +//! Some parameters are applicable only to particular light type; +//! calling methods unrelated to current type will throw an exception. +class Graphic3d_CLight : public Standard_Transient { - + DEFINE_STANDARD_RTTIEXT(Graphic3d_CLight, Standard_Transient) public: - Graphic3d_Vec3d Position; //!< light position - Graphic3d_Vec4 Color; //!< light color - Graphic3d_Vec4 Direction; //!< direction of directional/spot light - Graphic3d_Vec4 Params; //!< packed light parameters - Standard_ShortReal Smoothness; //!< radius (cone angle) for point (directional) light - Standard_ShortReal Intensity; //!< intensity multiplier for light - Graphic3d_TypeOfLightSource Type; //!< Graphic3d_TypeOfLightSource enumeration - Standard_Boolean IsHeadlight; //!< flag to mark head light + //! Empty constructor, which should be followed by light source properties configuration. + Standard_EXPORT Graphic3d_CLight (Graphic3d_TypeOfLightSource theType); - //! Const attenuation factor of positional light source - Standard_ShortReal ConstAttenuation() const { return Params.x(); } + //! Returns the Type of the Light, cannot be changed after object construction. + Graphic3d_TypeOfLightSource Type() const { return myType; } - //! Linear attenuation factor of positional light source - Standard_ShortReal LinearAttenuation() const { return Params.y(); } + //! Returns light source name; empty string by default. + const TCollection_AsciiString& Name() const { return myName; } - //! Const, Linear attenuation factors of positional light source - Graphic3d_Vec2 Attenuation() const { return Params.xy(); } + //! Sets light source name. + void SetName (const TCollection_AsciiString& theName) { myName = theName; } - //! Angle in radians of the cone created by the spot - Standard_ShortReal Angle() const { return Params.z(); } + //! Returns the color of the light source; WHITE by default. + const Quantity_Color& Color() const { return myColor.GetRGB(); } - //! Intensity distribution of the spot light, with 0..1 range. - Standard_ShortReal Concentration() const { return Params.w(); } + //! Defines the color of a light source by giving the basic color. + Standard_EXPORT void SetColor (const Quantity_Color& theColor); - Standard_ShortReal& ChangeConstAttenuation() { return Params.x(); } - Standard_ShortReal& ChangeLinearAttenuation() { return Params.y(); } - Graphic3d_Vec2& ChangeAttenuation() { return Params.xy(); } - Standard_ShortReal& ChangeAngle() { return Params.z(); } - Standard_ShortReal& ChangeConcentration() { return Params.w(); } + //! Check that the light source is turned on; TRUE by default. + //! This flag affects all occurrences of light sources, where it was registered and activated; + //! so that it is possible defining an active light in View which is actually in disabled state. + Standard_Boolean IsEnabled() const { return myIsEnabled; } + //! Change enabled state of the light state. + //! This call does not remove or deactivate light source in Views/Viewers; + //! instead it turns it OFF so that it just have no effect. + Standard_EXPORT void SetEnabled (Standard_Boolean theIsOn); + + //! Returns true if the light is a headlight; FALSE by default. + //! Headlight flag means that light position/direction are defined not in a World coordinate system, but relative to the camera orientation. + Standard_Boolean IsHeadlight() const { return myIsHeadlight; } + + //! Alias for IsHeadlight(). + Standard_Boolean Headlight() const { return myIsHeadlight; } + + //! Setup headlight flag. + Standard_EXPORT void SetHeadlight (Standard_Boolean theValue); + +//! @name positional/spot light properties public: - //! Empty constructor - Graphic3d_CLight() - : Position (0.0, 0.0, 0.0), - Color (1.0f, 1.0f, 1.0f, 1.0f), - Direction (0.0f, 0.0f, 0.0f, 0.0f), - Params (0.0f, 0.0f, 0.0f, 0.0f), - Smoothness (0.0f), - Intensity (1.0f), - Type (Graphic3d_TOLS_AMBIENT), - IsHeadlight (Standard_False) + //! Returns location of positional/spot light; (0, 0, 0) by default. + const gp_Pnt& Position() const { return myPosition; } + + //! Setup location of positional/spot light. + Standard_EXPORT void SetPosition (const gp_Pnt& thePosition); + + //! Returns location of positional/spot light. + void Position (Standard_Real& theX, + Standard_Real& theY, + Standard_Real& theZ) const { - // + theX = myPosition.X(); + theY = myPosition.Y(); + theZ = myPosition.Z(); } + //! Setup location of positional/spot light. + void SetPosition (Standard_Real theX, Standard_Real theY, Standard_Real theZ) { SetPosition (gp_Pnt (theX, theY, theZ)); } + + //! Returns constant attenuation factor of positional/spot light source; 1.0f by default. + //! Distance attenuation factors of reducing positional/spot light intensity depending on the distance from its position: + //! @code + //! float anAttenuation = 1.0 / (ConstAttenuation() + LinearAttenuation() * theDistance + QuadraticAttenuation() * theDistance * theDistance); + //! @endcode + Standard_ShortReal ConstAttenuation() const { return myParams.x(); } + + //! Returns linear attenuation factor of positional/spot light source; 0.0 by default. + //! Distance attenuation factors of reducing positional/spot light intensity depending on the distance from its position: + //! @code + //! float anAttenuation = 1.0 / (ConstAttenuation() + LinearAttenuation() * theDistance + QuadraticAttenuation() * theDistance * theDistance); + //! @endcode + Standard_ShortReal LinearAttenuation() const { return myParams.y(); } + + //! Returns the attenuation factors. + void Attenuation (Standard_Real& theConstAttenuation, + Standard_Real& theLinearAttenuation) const + { + theConstAttenuation = ConstAttenuation(); + theLinearAttenuation = LinearAttenuation(); + } + + //! Defines the coefficients of attenuation; values should be >= 0.0 and their summ should not be equal to 0. + Standard_EXPORT void SetAttenuation (Standard_ShortReal theConstAttenuation, + Standard_ShortReal theLinearAttenuation); + +//! @name directional/spot light additional properties public: - DEFINE_STANDARD_ALLOC + //! Returns direction of directional/spot light. + gp_Dir Direction() const { return gp_Dir (myDirection.x(), myDirection.y(), myDirection.z()); } + + //! Sets direction of directional/spot light. + Standard_EXPORT void SetDirection (const gp_Dir& theDir); + + //! Returns the theVx, theVy, theVz direction of the light source. + void Direction (Standard_Real& theVx, + Standard_Real& theVy, + Standard_Real& theVz) const + { + theVx = myDirection.x(); + theVy = myDirection.y(); + theVz = myDirection.z(); + } + + //! Sets direction of directional/spot light. + void SetDirection (Standard_Real theVx, Standard_Real theVy, Standard_Real theVz) { SetDirection (gp_Dir (theVx, theVy, theVz)); } + +//! @name spotlight additional definition parameters +public: + + //! Returns an angle in radians of the cone created by the spot; 30 degrees by default. + Standard_ShortReal Angle() const { return myParams.z(); } + + //! Angle in radians of the cone created by the spot, should be within range (0.0, M_PI). + Standard_EXPORT void SetAngle (Standard_ShortReal theAngle); + + //! Returns intensity distribution of the spot light, within [0.0, 1.0] range; 1.0 by default. + //! This coefficient should be converted into spotlight exponent within [0.0, 128.0] range: + //! @code + //! float aSpotExponent = Concentration() * 128.0; + //! anAttenuation *= pow (aCosA, aSpotExponent);" + //! @endcode + //! The concentration factor determines the dispersion of the light on the surface, the default value (1.0) corresponds to a minimum of dispersion. + Standard_ShortReal Concentration() const { return myParams.w(); } + + //! Defines the coefficient of concentration; value should be within range [0.0, 1.0]. + Standard_EXPORT void SetConcentration (Standard_ShortReal theConcentration); + +//! @name Ray-Tracing / Path-Tracing light properties +public: + + //! Returns the intensity of light source; 1.0 by default. + Standard_ShortReal Intensity() const { return myIntensity; } + + //! Modifies the intensity of light source, which should be > 0.0. + Standard_EXPORT void SetIntensity (Standard_ShortReal theValue); + + //! Returns the smoothness of light source (either smoothing angle for directional light or smoothing radius in case of positional light); 0.0 by default. + Standard_ShortReal Smoothness() const { return mySmoothness; } + + //! Modifies the smoothing radius of positional/spot light; should be >= 0.0. + Standard_EXPORT void SetSmoothRadius (Standard_ShortReal theValue); + + //! Modifies the smoothing angle (in radians) of directional light source; should be within range [0.0, M_PI/2]. + Standard_EXPORT void SetSmoothAngle (Standard_ShortReal theValue); + +//! @name low-level access methods +public: + + //! @return light resource identifier string + const TCollection_AsciiString& GetId() const { return myId; } + + //! Packed light parameters. + const Graphic3d_Vec4& PackedParams() const { return myParams; } + + //! Returns the color of the light source with dummy Alpha component, which should be ignored. + const Graphic3d_Vec4& PackedColor() const { return myColor; } + + //! Returns direction of directional/spot light. + const Graphic3d_Vec4& PackedDirection() const { return myDirection; } + + //! @return modification counter + Standard_Size Revision() const { return myRevision; } + +private: + + //! Access positional/spot light constant attenuation coefficient from packed vector. + Standard_ShortReal& changeConstAttenuation() { return myParams.x(); } + + //! Access positional/spot light linear attenuation coefficient from packed vector. + Standard_ShortReal& changeLinearAttenuation() { return myParams.y(); } + + //! Access spotlight angle parameter from packed vector. + Standard_ShortReal& changeAngle() { return myParams.z(); } + + //! Access spotlight concentration parameter from packed vector. + Standard_ShortReal& changeConcentration() { return myParams.w(); } + +private: + + //! Generate unique object id. + void makeId(); + + //! Update modification counter. + void updateRevisionIf (bool theIsModified) + { + if (theIsModified) + { + ++myRevision; + } + } + +private: + + Graphic3d_CLight (const Graphic3d_CLight& ); + Graphic3d_CLight& operator= (const Graphic3d_CLight& ); + +protected: + + TCollection_AsciiString myId; //!< resource id + TCollection_AsciiString myName; //!< user given name + gp_Pnt myPosition; //!< light position + Quantity_ColorRGBA myColor; //!< light color + Graphic3d_Vec4 myDirection; //!< direction of directional/spot light + Graphic3d_Vec4 myParams; //!< packed light parameters + Standard_ShortReal mySmoothness; //!< radius for point light or cone angle for directional light + Standard_ShortReal myIntensity; //!< intensity multiplier for light + const Graphic3d_TypeOfLightSource myType; //!< Graphic3d_TypeOfLightSource enumeration + Standard_Size myRevision; //!< modification counter + Standard_Boolean myIsHeadlight; //!< flag to mark head light + Standard_Boolean myIsEnabled; //!< enabled state }; -typedef NCollection_List Graphic3d_ListOfCLight; +DEFINE_STANDARD_HANDLE(Graphic3d_CLight, Standard_Transient) #endif // Graphic3d_CLight_HeaderFile diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index 3856bf9f20..1129c4e726 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -409,10 +409,10 @@ public: virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) = 0; //! Returns list of lights of the view. - virtual const Graphic3d_ListOfCLight& Lights() const = 0; + virtual const Handle(Graphic3d_LightSet)& Lights() const = 0; //! Sets list of lights for the view. - virtual void SetLights (const Graphic3d_ListOfCLight& theLights) = 0; + virtual void SetLights (const Handle(Graphic3d_LightSet)& theLights) = 0; //! Returns list of clip planes set for the view. virtual const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const = 0; diff --git a/src/Graphic3d/Graphic3d_LightSet.cxx b/src/Graphic3d/Graphic3d_LightSet.cxx new file mode 100644 index 0000000000..0b51b700fd --- /dev/null +++ b/src/Graphic3d/Graphic3d_LightSet.cxx @@ -0,0 +1,146 @@ +// Copyright (c) 2017 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include + +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient) + +namespace +{ + //! Suffixes identifying light source type. + static const char THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_NB] = + { + 'a', // Graphic3d_TOLS_AMBIENT + 'd', // Graphic3d_TOLS_DIRECTIONAL + 'p', // Graphic3d_TOLS_POSITIONAL + 's' // Graphic3d_TOLS_SPOT + }; +} + +// ======================================================================= +// function : Graphic3d_LightSet +// purpose : +// ======================================================================= +Graphic3d_LightSet::Graphic3d_LightSet() +: myAmbient (0.0f, 0.0f, 0.0f, 0.0f), + myNbEnabled (0), + myRevision (1), + myCacheRevision (0) +{ + memset (myLightTypes, 0, sizeof(myLightTypes)); + memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled)); +} + +// ======================================================================= +// function : Add +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_LightSet::Add (const Handle(Graphic3d_CLight)& theLight) +{ + if (theLight.IsNull()) + { + throw Standard_ProgramError ("Graphic3d_LightSet::Add(), NULL argument"); + } + + const Standard_Integer anOldExtent = myLights.Extent(); + const Standard_Integer anIndex = myLights.Add (theLight, 0); + if (anIndex <= anOldExtent) + { + return Standard_False; + } + + myLightTypes[theLight->Type()] += 1; + myLights.ChangeFromIndex (anIndex) = theLight->Revision(); + ++myRevision; + return Standard_True; +} + +// ======================================================================= +// function : Remove +// purpose : +// ======================================================================= +Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& theLight) +{ + const Standard_Integer anIndToRemove = myLights.FindIndex (theLight); + if (anIndToRemove <= 0) + { + return Standard_False; + } + + ++myRevision; + myLights.RemoveFromIndex (anIndToRemove); + myLightTypes[theLight->Type()] -= 1; + return Standard_True; +} + +// ======================================================================= +// function : UpdateRevision +// purpose : +// ======================================================================= +Standard_Size Graphic3d_LightSet::UpdateRevision() +{ + if (myCacheRevision == myRevision) + { + // check implicit updates of light sources + for (NCollection_IndexedDataMap::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next()) + { + const Handle(Graphic3d_CLight)& aLight = aLightIter.Key(); + if (aLightIter.Value() != aLight->Revision()) + { + ++myRevision; + break; + } + } + } + if (myCacheRevision == myRevision) + { + return myRevision; + } + + myCacheRevision = myRevision; + myAmbient.SetValues (0.0f, 0.0f, 0.0f, 0.0f); + memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled)); + NCollection_LocalArray aKeyLong (myLights.Extent() + 1); + Standard_Integer aLightLast = 0; + for (NCollection_IndexedDataMap::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next()) + { + const Handle(Graphic3d_CLight)& aLight = aLightIter.Key(); + aLightIter.ChangeValue() = aLight->Revision(); + if (!aLight->IsEnabled()) + { + continue; + } + + myLightTypesEnabled[aLight->Type()] += 1; + if (aLight->Type() == Graphic3d_TOLS_AMBIENT) + { + myAmbient += aLight->PackedColor() * aLight->Intensity(); + } + else + { + aKeyLong[aLightLast++] = THE_LIGHT_KEY_LETTERS[aLight->Type()]; + } + } + aKeyLong[aLightLast] = '\0'; + myAmbient.a() = 1.0f; + myNbEnabled = myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] + + myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL] + + myLightTypesEnabled[Graphic3d_TOLS_SPOT]; + myKeyEnabledLong = aKeyLong; + myKeyEnabledShort = TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_DIRECTIONAL] : '\0') + + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_POSITIONAL] : '\0') + + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_SPOT] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_SPOT] : '\0'); + return myRevision; +} diff --git a/src/Graphic3d/Graphic3d_LightSet.hxx b/src/Graphic3d/Graphic3d_LightSet.hxx new file mode 100644 index 0000000000..418cdccb2a --- /dev/null +++ b/src/Graphic3d/Graphic3d_LightSet.hxx @@ -0,0 +1,190 @@ +// Copyright (c) 2017 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _Graphic3d_LightSet_HeaderFile +#define _Graphic3d_LightSet_HeaderFile + +#include +#include + +//! Class defining the set of light sources. +class Graphic3d_LightSet : public Standard_Transient +{ + DEFINE_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient) +public: + + //! Iteration filter flags. + enum IterationFilter + { + IterationFilter_None = 0x0000, //!< no filter + IterationFilter_ExcludeAmbient = 0x0002, //!< exclude ambient light sources + IterationFilter_ExcludeDisabled = 0x0004, //!< exclude disabled light sources + IterationFilter_ExcludeDisabledAndAmbient = IterationFilter_ExcludeAmbient | IterationFilter_ExcludeDisabled, + }; + + //! Iterator through light sources. + class Iterator + { + public: + //! Empty constructor. + Iterator() : myFilter (0) {} + + //! Constructor with initialization. + Iterator (const Graphic3d_LightSet& theSet, + IterationFilter theFilter = IterationFilter_None) + : myIter (theSet.myLights), + myFilter (theFilter) + { + skipFiltered(); + } + + //! Constructor with initialization. + Iterator (const Handle(Graphic3d_LightSet)& theSet, + IterationFilter theFilter = IterationFilter_None) + : myFilter (theFilter) + { + if (!theSet.IsNull()) + { + myIter = NCollection_IndexedDataMap::Iterator (theSet->myLights); + skipFiltered(); + } + } + + //! Returns TRUE if iterator points to a valid item. + Standard_Boolean More() const { return myIter.More(); } + + //! Returns current item. + const Handle(Graphic3d_CLight)& Value() const { return myIter.Key(); } + + //! Moves to the next item. + void Next() + { + myIter.Next(); + skipFiltered(); + } + + protected: + + //! Skip filtered items. + void skipFiltered() + { + if (myFilter == 0) + { + return; + } + + for (; myIter.More(); myIter.Next()) + { + if ((myFilter & IterationFilter_ExcludeAmbient) != 0 + && myIter.Key()->Type() == Graphic3d_TOLS_AMBIENT) + { + continue; + } + else if ((myFilter & IterationFilter_ExcludeDisabled) != 0 + && !myIter.Key()->IsEnabled()) + { + continue; + } + + break; + } + } + + protected: + NCollection_IndexedDataMap::Iterator myIter; + Standard_Integer myFilter; + }; + +public: + + //! Empty constructor. + Standard_EXPORT Graphic3d_LightSet(); + + //! Return lower light index. + Standard_Integer Lower() const { return 1; } + + //! Return upper light index. + Standard_Integer Upper() const { return myLights.Extent(); } + + //! Return TRUE if lights list is empty. + Standard_Boolean IsEmpty() const { return myLights.IsEmpty(); } + + //! Return number of light sources. + Standard_Integer Extent() const { return myLights.Extent(); } + + //! Return the light source for specified index within range [Lower(), Upper()]. + const Handle(Graphic3d_CLight)& Value (Standard_Integer theIndex) const { return myLights.FindKey (theIndex); } + + //! Return TRUE if light source is defined in this set. + Standard_Boolean Contains (const Handle(Graphic3d_CLight)& theLight) const { return myLights.Contains (theLight); } + + //! Append new light source. + Standard_EXPORT Standard_Boolean Add (const Handle(Graphic3d_CLight)& theLight); + + //! Remove light source. + Standard_EXPORT Standard_Boolean Remove (const Handle(Graphic3d_CLight)& theLight); + + //! Returns total amount of lights of specified type. + Standard_Integer NbLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypes[theType]; } + +//! @name cached state of lights set updated by UpdateRevision() +public: + + //! Update light sources revision. + Standard_EXPORT Standard_Size UpdateRevision(); + + //! Return light sources revision. + //! @sa UpdateRevision() + Standard_Size Revision() const { return myRevision; } + + //! Returns total amount of enabled lights EXCLUDING ambient. + //! @sa UpdateRevision() + Standard_Integer NbEnabled() const { return myNbEnabled; } + + //! Returns total amount of enabled lights of specified type. + //! @sa UpdateRevision() + Standard_Integer NbEnabledLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypesEnabled[theType]; } + + //! Returns cumulative ambient color, which is computed as sum of all enabled ambient light sources. + //! Values are NOT clamped (can be greater than 1.0f) and alpha component is fixed to 1.0f. + //! @sa UpdateRevision() + const Graphic3d_Vec4& AmbientColor() const { return myAmbient; } + + //! Returns a string defining a list of enabled light sources as concatenation of letters 'd' (Directional), 'p' (Point), 's' (Spot) + //! depending on the type of light source in the list. + //! Example: "dppp". + //! @sa UpdateRevision() + const TCollection_AsciiString& KeyEnabledLong() const { return myKeyEnabledLong; } + + //! Returns a string defining a list of enabled light sources as concatenation of letters 'd' (Directional), 'p' (Point), 's' (Spot) + //! depending on the type of light source in the list, specified only once. + //! Example: "dp". + //! @sa UpdateRevision() + const TCollection_AsciiString& KeyEnabledShort() const { return myKeyEnabledShort; } + +protected: + NCollection_IndexedDataMap + myLights; //!< list of light sources with their cached state (revision) + Graphic3d_Vec4 myAmbient; //!< cached value of cumulative ambient color + TCollection_AsciiString myKeyEnabledLong; //!< key identifying the list of enabled light sources by their type + TCollection_AsciiString myKeyEnabledShort; //!< key identifying the list of enabled light sources by the number of sources of each type + Standard_Integer myLightTypes [Graphic3d_TypeOfLightSource_NB]; //!< counters per each light source type defined in the list + Standard_Integer myLightTypesEnabled[Graphic3d_TypeOfLightSource_NB]; //!< counters per each light source type enabled in the list + Standard_Integer myNbEnabled; //!< number of enabled light sources, excluding ambient + Standard_Size myRevision; //!< current revision of light source set + Standard_Size myCacheRevision; //!< revision of cached state +}; + +DEFINE_STANDARD_HANDLE(Graphic3d_LightSet, Standard_Transient) + +#endif // _Graphic3d_LightSet_HeaderFile diff --git a/src/Graphic3d/Graphic3d_TypeOfLightSource.hxx b/src/Graphic3d/Graphic3d_TypeOfLightSource.hxx index 17a923a8ed..4f4e43b262 100644 --- a/src/Graphic3d/Graphic3d_TypeOfLightSource.hxx +++ b/src/Graphic3d/Graphic3d_TypeOfLightSource.hxx @@ -17,18 +17,24 @@ #ifndef _Graphic3d_TypeOfLightSource_HeaderFile #define _Graphic3d_TypeOfLightSource_HeaderFile -//! Definition of all the type of light sources -//! -//! TOLS_AMBIENT ambient light -//! TOLS_DIRECTIONAL directional light -//! TOLS_POSITIONAL positional light -//! TOLS_SPOT spot light +//! Definition of all the type of light source. enum Graphic3d_TypeOfLightSource { - Graphic3d_TOLS_AMBIENT, - Graphic3d_TOLS_DIRECTIONAL, - Graphic3d_TOLS_POSITIONAL, - Graphic3d_TOLS_SPOT + Graphic3d_TOLS_AMBIENT, //!< ambient light + Graphic3d_TOLS_DIRECTIONAL, //!< directional light + Graphic3d_TOLS_POSITIONAL, //!< positional light + Graphic3d_TOLS_SPOT, //!< spot light + // obsolete aliases + V3d_AMBIENT = Graphic3d_TOLS_AMBIENT, + V3d_DIRECTIONAL = Graphic3d_TOLS_DIRECTIONAL, + V3d_POSITIONAL = Graphic3d_TOLS_POSITIONAL, + V3d_SPOT = Graphic3d_TOLS_SPOT +}; + +enum +{ + //! Auxiliary value defining the overall number of values in enumeration Graphic3d_TypeOfLightSource + Graphic3d_TypeOfLightSource_NB = Graphic3d_TOLS_SPOT + 1 }; #endif // _Graphic3d_TypeOfLightSource_HeaderFile diff --git a/src/Graphic3d/Graphic3d_TypeOfShadingModel.hxx b/src/Graphic3d/Graphic3d_TypeOfShadingModel.hxx index b889d4c8b3..071261888b 100644 --- a/src/Graphic3d/Graphic3d_TypeOfShadingModel.hxx +++ b/src/Graphic3d/Graphic3d_TypeOfShadingModel.hxx @@ -30,4 +30,10 @@ enum Graphic3d_TypeOfShadingModel Graphic3d_TOSM_FRAGMENT }; +enum +{ + //! Auxiliary value defining the overall number of values in enumeration Graphic3d_TypeOfShadingModel + Graphic3d_TypeOfShadingModel_NB = Graphic3d_TOSM_FRAGMENT + 1 +}; + #endif // _Graphic3d_TypeOfShadingModel_HeaderFile diff --git a/src/Graphic3d/Graphic3d_ZLayerSettings.hxx b/src/Graphic3d/Graphic3d_ZLayerSettings.hxx index 826ee0aae7..c7eab89702 100644 --- a/src/Graphic3d/Graphic3d_ZLayerSettings.hxx +++ b/src/Graphic3d/Graphic3d_ZLayerSettings.hxx @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -48,6 +49,13 @@ struct Graphic3d_ZLayerSettings //! Set custom name. void SetName (const TCollection_AsciiString& theName) { myName = theName; } + //! Return lights list to be used for rendering presentations within this Z-Layer; NULL by default. + //! NULL list (but not empty list!) means that default lights assigned to the View should be used instead of per-layer lights. + const Handle(Graphic3d_LightSet)& Lights() const { return myLights; } + + //! Assign lights list to be used. + void SetLights (const Handle(Graphic3d_LightSet)& theLights) { myLights = theLights; } + //! Return the origin of all objects within the layer. const gp_XYZ& Origin() const { return myOrigin; } @@ -193,6 +201,7 @@ struct Graphic3d_ZLayerSettings protected: TCollection_AsciiString myName; //!< user-provided name + Handle(Graphic3d_LightSet) myLights; //!< lights list Handle(Geom_Transformation) myOriginTrsf; //!< transformation to the origin gp_XYZ myOrigin; //!< the origin of all objects within the layer Standard_Real myCullingDistance; //!< distance to discard objects diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 61597805cd..64fa0dece8 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -33,7 +33,6 @@ OpenGl_View.hxx OpenGl_View.cxx OpenGl_View_Raytrace.cxx OpenGl_View_Redraw.cxx -OpenGl_Light.hxx OpenGl_GraduatedTrihedron.hxx OpenGl_GraduatedTrihedron.cxx OpenGl_MapOfZLayerSettings.hxx diff --git a/src/OpenGl/OpenGl_Layer.cxx b/src/OpenGl/OpenGl_Layer.cxx index e5e94cf03f..929c927135 100644 --- a/src/OpenGl/OpenGl_Layer.cxx +++ b/src/OpenGl/OpenGl_Layer.cxx @@ -680,6 +680,15 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull(); const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); + const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager(); + Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources(); + const bool hasOwnLights = aCtx->ColorMask() && !myLayerSettings.Lights().IsNull() && myLayerSettings.Lights() != aLightsBack; + if (hasOwnLights) + { + myLayerSettings.Lights()->UpdateRevision(); + aManager->UpdateLightSourceStateTo (myLayerSettings.Lights()); + } + const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera(); if (hasLocalCS) { @@ -731,6 +740,10 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace, // render priority list renderAll (theWorkspace); + if (hasOwnLights) + { + aManager->UpdateLightSourceStateTo (aLightsBack); + } if (hasLocalCS) { aCtx->ShaderManager()->RevertClippingState(); diff --git a/src/OpenGl/OpenGl_LayerList.cxx b/src/OpenGl/OpenGl_LayerList.cxx index 51dbc606c7..4bcd58ac14 100644 --- a/src/OpenGl/OpenGl_LayerList.cxx +++ b/src/OpenGl/OpenGl_LayerList.cxx @@ -568,6 +568,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, Standard_Integer aClearDepthLayerPrev = -1, aClearDepthLayer = -1; const bool toPerformDepthPrepass = theWorkspace->View()->RenderingParams().ToEnableDepthPrepass && aPrevSettings.DepthMask == GL_TRUE; + const Handle(Graphic3d_LightSet) aLightsBack = aCtx->ShaderManager()->LightSourceState().LightSources(); for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, myDefaultLayerIndex, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();) { bool hasSkippedDepthLayers = false; @@ -576,6 +577,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, if (aPassIter == 0) { aCtx->SetColorMask (false); + aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)()); aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc; aDefaultSettings.DepthMask = GL_TRUE; } @@ -586,11 +588,13 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace, continue; } aCtx->SetColorMask (true); + aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack); aDefaultSettings = aPrevSettings; } else if (aPassIter == 2) { aCtx->SetColorMask (true); + aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack); if (toPerformDepthPrepass) { aDefaultSettings.DepthFunc = GL_EQUAL; diff --git a/src/OpenGl/OpenGl_Light.hxx b/src/OpenGl/OpenGl_Light.hxx deleted file mode 100644 index d1c0c36a3d..0000000000 --- a/src/OpenGl/OpenGl_Light.hxx +++ /dev/null @@ -1,27 +0,0 @@ -// Created on: 2011-07-13 -// Created by: Sergey ZERCHANINOV -// Copyright (c) 2011-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#ifndef OpenGl_Light_Header -#define OpenGl_Light_Header - -#include -#include - -#define OpenGLMaxLights 8 - -typedef Graphic3d_CLight OpenGl_Light; -typedef Graphic3d_ListOfCLight OpenGl_ListOfLight; - -#endif // OpenGl_Light_Header diff --git a/src/OpenGl/OpenGl_SceneGeometry.cxx b/src/OpenGl/OpenGl_SceneGeometry.cxx index 6b72d90829..530bf57048 100644 --- a/src/OpenGl/OpenGl_SceneGeometry.cxx +++ b/src/OpenGl/OpenGl_SceneGeometry.cxx @@ -108,7 +108,7 @@ OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient, } // ======================================================================= -// function : OpenGl_LightSource +// function : OpenGl_RaytraceLight // purpose : Creates new light source // ======================================================================= OpenGl_RaytraceLight::OpenGl_RaytraceLight (const BVH_Vec4f& theEmission, diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 5faea4161f..fe84caca72 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -32,6 +32,25 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient) namespace { + //! Suffixes identifying shading model. + static const char THE_SHADINGMODEL_KEY_LETTERS[Graphic3d_TypeOfShadingModel_NB] = + { + 'c', // Graphic3d_TOSM_NONE + 'f', // Graphic3d_TOSM_FACET + 'g', // Graphic3d_TOSM_VERTEX + 'p' // Graphic3d_TOSM_FRAGMENT + }; + + //! Number specifying maximum number of light sources to prepare a GLSL program with unrolled loop. + const Standard_Integer THE_NB_UNROLLED_LIGHTS_MAX = 32; + + //! Compute the size of array storing holding light sources definition. + static Standard_Integer roundUpMaxLightSources (Standard_Integer theNbLights) + { + Standard_Integer aMaxLimit = THE_NB_UNROLLED_LIGHTS_MAX; + for (; aMaxLimit < theNbLights; aMaxLimit *= 2) {} + return aMaxLimit; + } #define EOL "\n" @@ -260,31 +279,32 @@ const char THE_FRAG_write_oit_buffers[] = static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f; //! Bind FFP light source. - static void bindLight (const OpenGl_Light& theLight, + static void bindLight (const Graphic3d_CLight& theLight, const GLenum theLightGlId, const OpenGl_Mat4& theModelView, OpenGl_Context* theCtx) { // the light is a headlight? - if (theLight.IsHeadlight) + if (theLight.IsHeadlight()) { theCtx->core11->glMatrixMode (GL_MODELVIEW); theCtx->core11->glLoadIdentity(); } // setup light type - switch (theLight.Type) + const Graphic3d_Vec4& aLightColor = theLight.PackedColor(); + switch (theLight.Type()) { case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method case Graphic3d_TOLS_DIRECTIONAL: { // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one - const OpenGl_Vec4 anInfDir = -theLight.Direction; + const OpenGl_Vec4 anInfDir = -theLight.PackedDirection(); // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE. theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); - theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); - theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, aLightColor.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, aLightColor.GetData()); theCtx->core11->glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData()); theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); @@ -294,10 +314,10 @@ const char THE_FRAG_write_oit_buffers[] = case Graphic3d_TOLS_POSITIONAL: { // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE - const OpenGl_Vec4 aPosition (static_cast(theLight.Position.x()), static_cast(theLight.Position.y()), static_cast(theLight.Position.z()), 1.0f); + const OpenGl_Vec4 aPosition (static_cast(theLight.Position().X()), static_cast(theLight.Position().Y()), static_cast(theLight.Position().Z()), 1.0f); theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); - theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); - theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, aLightColor.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, aLightColor.GetData()); theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData()); theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); @@ -309,12 +329,12 @@ const char THE_FRAG_write_oit_buffers[] = } case Graphic3d_TOLS_SPOT: { - const OpenGl_Vec4 aPosition (static_cast(theLight.Position.x()), static_cast(theLight.Position.y()), static_cast(theLight.Position.z()), 1.0f); + const OpenGl_Vec4 aPosition (static_cast(theLight.Position().X()), static_cast(theLight.Position().Y()), static_cast(theLight.Position().Z()), 1.0f); theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); - theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); - theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE, aLightColor.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR, aLightColor.GetData()); theCtx->core11->glLightfv (theLightGlId, GL_POSITION, aPosition.GetData()); - theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData()); + theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.PackedDirection().GetData()); theCtx->core11->glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f); theCtx->core11->glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI)); theCtx->core11->glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); @@ -325,7 +345,7 @@ const char THE_FRAG_write_oit_buffers[] = } // restore matrix in case of headlight - if (theLight.IsHeadlight) + if (theLight.IsHeadlight()) { theCtx->core11->glLoadMatrixf (theModelView.GetData()); } @@ -476,34 +496,27 @@ Standard_Boolean OpenGl_ShaderManager::IsEmpty() const // ======================================================================= void OpenGl_ShaderManager::switchLightPrograms() { + const Handle(Graphic3d_LightSet)& aLights = myLightSourceState.LightSources(); TCollection_AsciiString aKey; - switch (myShadingModel) + if (!aLights.IsNull()) { - case Graphic3d_TOSM_NONE: aKey = "c_"; break; - case Graphic3d_TOSM_FACET: aKey = "f_"; break; - case Graphic3d_TOSM_VERTEX: aKey = "g_"; break; - case Graphic3d_TOSM_FRAGMENT: aKey = "p_"; break; - } - const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources(); - if (aLights != NULL) - { - for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next()) + aKey = THE_SHADINGMODEL_KEY_LETTERS[myShadingModel]; + aKey += "_"; + if (aLights->NbEnabled() <= THE_NB_UNROLLED_LIGHTS_MAX) { - switch (aLightIter.Value().Type) - { - case Graphic3d_TOLS_AMBIENT: - break; // skip ambient - case Graphic3d_TOLS_DIRECTIONAL: - aKey += "d"; - break; - case Graphic3d_TOLS_POSITIONAL: - aKey += "p"; - break; - case Graphic3d_TOLS_SPOT: - aKey += "s"; - break; - } + aKey += aLights->KeyEnabledLong(); } + else + { + const Standard_Integer aMaxLimit = roundUpMaxLightSources (aLights->NbEnabled()); + aKey += aLights->KeyEnabledShort(); + aKey += aMaxLimit; + } + } + else + { + aKey = THE_SHADINGMODEL_KEY_LETTERS[Graphic3d_TOSM_NONE]; + aKey += "_"; } if (!myMapOfLightPrograms.Find (aKey, myLightPrograms)) @@ -517,7 +530,7 @@ void OpenGl_ShaderManager::switchLightPrograms() // function : UpdateLightSourceStateTo // purpose : Updates state of OCCT light sources // ======================================================================= -void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights) +void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights) { myLightSourceState.Set (theLights); myLightSourceState.Update(); @@ -594,32 +607,25 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr } GLenum aLightGlId = GL_LIGHT0; - OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f); const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix(); - if (myLightSourceState.LightSources() != NULL) + for (Graphic3d_LightSet::Iterator aLightIt (myLightSourceState.LightSources(), Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); + aLightIt.More(); aLightIt.Next()) { - for (Graphic3d_ListOfCLight::Iterator aLightIt (*myLightSourceState.LightSources()); aLightIt.More(); aLightIt.Next()) + if (aLightGlId > GL_LIGHT7) // only 8 lights in FFP... { - const Graphic3d_CLight& aLight = aLightIt.Value(); - if (aLight.Type == Graphic3d_TOLS_AMBIENT) - { - anAmbient += aLight.Color; - continue; - } - else if (aLightGlId > GL_LIGHT7) // only 8 lights in FFP... - { - myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM, - "Warning: light sources limit (8) has been exceeded within Fixed-function pipeline."); - continue; - } - - bindLight (aLight, aLightGlId, aModelView, myContext); - ++aLightGlId; + myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM, + "Warning: light sources limit (8) has been exceeded within Fixed-function pipeline."); + continue; } + + bindLight (*aLightIt.Value(), aLightGlId, aModelView, myContext); + ++aLightGlId; } // apply accumulated ambient color - anAmbient.a() = 1.0f; + const Graphic3d_Vec4 anAmbient = !myLightSourceState.LightSources().IsNull() + ? myLightSourceState.LightSources()->AmbientColor() + : Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 1.0f); myContext->core11->glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbient.GetData()); // GL_LIGHTING is managed by drawers to switch between shaded / no lighting output, @@ -659,7 +665,7 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr myLightTypeArray.ChangeValue (aLightIt).Type = -1; } - if (myLightSourceState.LightSources() == NULL + if (myLightSourceState.LightSources().IsNull() || myLightSourceState.LightSources()->IsEmpty()) { theProgram->SetUniform (myContext, @@ -675,17 +681,12 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr return; } - OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f); Standard_Integer aLightsNb = 0; - for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next()) + for (Graphic3d_LightSet::Iterator anIter (myLightSourceState.LightSources(), Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); + anIter.More(); anIter.Next()) { - const OpenGl_Light& aLight = anIter.Value(); - if (aLight.Type == Graphic3d_TOLS_AMBIENT) - { - anAmbient += aLight.Color; - continue; - } - else if (aLightsNb >= aNbLightsMax) + const Graphic3d_CLight& aLight = *anIter.Value(); + if (aLightsNb >= aNbLightsMax) { if (aNbLightsMax != 0) { @@ -697,36 +698,47 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr OpenGl_ShaderLightType& aLightType = myLightTypeArray.ChangeValue (aLightsNb); OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray.ChangeValue (aLightsNb); - aLightType.Type = aLight.Type; - aLightType.IsHeadlight = aLight.IsHeadlight; - aLightParams.Color = aLight.Color; - if (aLight.Type == Graphic3d_TOLS_DIRECTIONAL) + if (!aLight.IsEnabled()) // has no affect with Graphic3d_LightSet::IterationFilter_ExcludeDisabled - here just for consistency { - aLightParams.Position = -aLight.Direction; + // if it is desired to keep disabled light in the same order - we can replace it with a black light so that it will have no influence on result + aLightType.Type = -1; // Graphic3d_TOLS_AMBIENT can be used instead + aLightType.IsHeadlight = false; + aLightParams.Color = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f); + ++aLightsNb; + continue; } - else if (!aLight.IsHeadlight) + + aLightType.Type = aLight.Type(); + aLightType.IsHeadlight = aLight.IsHeadlight(); + aLightParams.Color = aLight.PackedColor(); + if (aLight.Type() == Graphic3d_TOLS_DIRECTIONAL) { - aLightParams.Position.x() = static_cast(aLight.Position.x() - myLocalOrigin.X()); - aLightParams.Position.y() = static_cast(aLight.Position.y() - myLocalOrigin.Y()); - aLightParams.Position.z() = static_cast(aLight.Position.z() - myLocalOrigin.Z()); + aLightParams.Position = -aLight.PackedDirection(); + } + else if (!aLight.IsHeadlight()) + { + aLightParams.Position.x() = static_cast(aLight.Position().X() - myLocalOrigin.X()); + aLightParams.Position.y() = static_cast(aLight.Position().Y() - myLocalOrigin.Y()); + aLightParams.Position.z() = static_cast(aLight.Position().Z() - myLocalOrigin.Z()); aLightParams.Position.w() = 1.0f; } else { - aLightParams.Position.x() = static_cast(aLight.Position.x()); - aLightParams.Position.y() = static_cast(aLight.Position.y()); - aLightParams.Position.z() = static_cast(aLight.Position.z()); + aLightParams.Position.x() = static_cast(aLight.Position().X()); + aLightParams.Position.y() = static_cast(aLight.Position().Y()); + aLightParams.Position.z() = static_cast(aLight.Position().Z()); aLightParams.Position.w() = 1.0f; } - if (aLight.Type == Graphic3d_TOLS_SPOT) + if (aLight.Type() == Graphic3d_TOLS_SPOT) { - aLightParams.Direction = aLight.Direction; + aLightParams.Direction = aLight.PackedDirection(); } - aLightParams.Parameters = aLight.Params; + aLightParams.Parameters = aLight.PackedParams(); ++aLightsNb; } + const Graphic3d_Vec4& anAmbient = myLightSourceState.LightSources()->AmbientColor(); theProgram->SetUniform (myContext, theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT), aLightsNb); @@ -1664,52 +1676,96 @@ TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TColl TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights, Standard_Boolean theHasVertColor) { - Standard_Integer aLightsMap[Graphic3d_TOLS_SPOT + 1] = { 0, 0, 0, 0 }; TCollection_AsciiString aLightsFunc, aLightsLoop; - const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources(); - if (aLights != NULL) theNbLights = 0; + const Handle(Graphic3d_LightSet)& aLights = myLightSourceState.LightSources(); + if (!aLights.IsNull()) { - Standard_Integer anIndex = 0; - for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex) + theNbLights = aLights->NbEnabled(); + if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX) { - switch (aLightIter.Value().Type) + Standard_Integer anIndex = 0; + for (Graphic3d_LightSet::Iterator aLightIter (aLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); + aLightIter.More(); aLightIter.Next(), ++anIndex) { - case Graphic3d_TOLS_AMBIENT: - --anIndex; - break; // skip ambient - case Graphic3d_TOLS_DIRECTIONAL: - aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);"; - break; - case Graphic3d_TOLS_POSITIONAL: - aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);"; - break; - case Graphic3d_TOLS_SPOT: - aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);"; - break; + switch (aLightIter.Value()->Type()) + { + case Graphic3d_TOLS_AMBIENT: + --anIndex; + break; // skip ambient + case Graphic3d_TOLS_DIRECTIONAL: + aLightsLoop = aLightsLoop + EOL" directionalLight (" + anIndex + ", theNormal, theView, theIsFront);"; + break; + case Graphic3d_TOLS_POSITIONAL: + aLightsLoop = aLightsLoop + EOL" pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);"; + break; + case Graphic3d_TOLS_SPOT: + aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);"; + break; + } } - aLightsMap[aLightIter.Value().Type] += 1; } - theNbLights = anIndex; - const Standard_Integer aNbLoopLights = aLightsMap[Graphic3d_TOLS_DIRECTIONAL] - + aLightsMap[Graphic3d_TOLS_POSITIONAL] - + aLightsMap[Graphic3d_TOLS_SPOT]; - if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] == 1 - && aNbLoopLights == 1) + else + { + theNbLights = roundUpMaxLightSources (theNbLights); + bool isFirstInLoop = true; + aLightsLoop = aLightsLoop + + EOL" for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)" + EOL" {" + EOL" int aType = occLight_Type (anIndex);"; + if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0) + { + isFirstInLoop = false; + aLightsLoop += + EOL" if (aType == OccLightType_Direct)" + EOL" {" + EOL" directionalLight (anIndex, theNormal, theView, theIsFront);" + EOL" }"; + } + if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0) + { + if (!isFirstInLoop) + { + aLightsLoop += EOL" else "; + } + isFirstInLoop = false; + aLightsLoop += + EOL" if (aType == OccLightType_Point)" + EOL" {" + EOL" pointLight (anIndex, theNormal, theView, aPoint, theIsFront);" + EOL" }"; + } + if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0) + { + if (!isFirstInLoop) + { + aLightsLoop += EOL" else "; + } + isFirstInLoop = false; + aLightsLoop += + EOL" if (aType == OccLightType_Spot)" + EOL" {" + EOL" spotLight (anIndex, theNormal, theView, aPoint, theIsFront);" + EOL" }"; + } + aLightsLoop += EOL" }"; + } + if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) == 1 + && theNbLights == 1) { // use the version with hard-coded first index aLightsLoop = EOL" directionalLightFirst(theNormal, theView, theIsFront);"; aLightsFunc += THE_FUNC_directionalLightFirst; } - else if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] > 0) + else if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0) { aLightsFunc += THE_FUNC_directionalLight; } - if (aLightsMap[Graphic3d_TOLS_POSITIONAL] > 0) + if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0) { aLightsFunc += THE_FUNC_pointLight; } - if (aLightsMap[Graphic3d_TOLS_SPOT] > 0) + if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0) { aLightsFunc += THE_FUNC_spotLight; } diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index 17add9fcbd..b1b4900ca0 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -204,7 +204,7 @@ public: const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; } //! Updates state of OCCT light sources. - Standard_EXPORT void UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights); + Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights); //! Invalidate state of OCCT light sources. Standard_EXPORT void UpdateLightSourceState(); diff --git a/src/OpenGl/OpenGl_ShaderStates.cxx b/src/OpenGl/OpenGl_ShaderStates.cxx index fa7506691c..2aeaf2655a 100755 --- a/src/OpenGl/OpenGl_ShaderStates.cxx +++ b/src/OpenGl/OpenGl_ShaderStates.cxx @@ -160,34 +160,6 @@ const OpenGl_Mat4& OpenGl_WorldViewState::WorldViewMatrixInverse() const return myWorldViewMatrixInverse; } -// ======================================================================= -// function : OpenGl_LightSourceState -// purpose : Creates uninitialized state of light sources -// ======================================================================= -OpenGl_LightSourceState::OpenGl_LightSourceState() -: myLightSources (NULL) -{ - // -} - -// ======================================================================= -// function : Set -// purpose : Sets new light sources -// ======================================================================= -void OpenGl_LightSourceState::Set (const OpenGl_ListOfLight* theLightSources) -{ - myLightSources = theLightSources; -} - -// ======================================================================= -// function : LightSources -// purpose : Returns current list of light sources -// ======================================================================= -const OpenGl_ListOfLight* OpenGl_LightSourceState::LightSources() const -{ - return myLightSources; -} - // ======================================================================= // function : OpenGl_ClippingState // purpose : Creates new clipping state diff --git a/src/OpenGl/OpenGl_ShaderStates.hxx b/src/OpenGl/OpenGl_ShaderStates.hxx index 786b27e613..eaa5abe337 100755 --- a/src/OpenGl/OpenGl_ShaderStates.hxx +++ b/src/OpenGl/OpenGl_ShaderStates.hxx @@ -17,8 +17,8 @@ #define _OpenGl_State_HeaderFile #include +#include #include -#include #include //! Defines interface for OpenGL state. @@ -122,17 +122,17 @@ class OpenGl_LightSourceState : public OpenGl_StateInterface public: //! Creates uninitialized state of light sources. - Standard_EXPORT OpenGl_LightSourceState(); + OpenGl_LightSourceState() {} //! Sets new light sources. - Standard_EXPORT void Set (const OpenGl_ListOfLight* theLightSources); + void Set (const Handle(Graphic3d_LightSet)& theLightSources) { myLightSources = theLightSources; } //! Returns current list of light sources. - Standard_EXPORT const OpenGl_ListOfLight* LightSources() const; + const Handle(Graphic3d_LightSet)& LightSources() const { return myLightSources; } private: - const OpenGl_ListOfLight* myLightSources; //!< List of OCCT light sources + Handle(Graphic3d_LightSet) myLightSources; //!< List of OCCT light sources }; diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 45182424d0..1735b1d413 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -62,6 +62,8 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, myToShowGradTrihedron (false), myZLayers (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1), myStateCounter (theCounter), + myCurrLightSourceState (theCounter->Increment()), + myLightsRevision (0), myLastLightSourceState (0, 0), #if !defined(GL_ES_VERSION_2_0) myFboColorFormat (GL_RGBA8), @@ -98,15 +100,12 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr, { myWorkspace = new OpenGl_Workspace (this, NULL); - OpenGl_Light aLight; - aLight.Type = Graphic3d_TOLS_AMBIENT; - aLight.IsHeadlight = Standard_False; - aLight.Color.r() = 1.; - aLight.Color.g() = 1.; - aLight.Color.b() = 1.; - myNoShadingLight.Append (aLight); + Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT); + aLight->SetHeadlight (false); + aLight->SetColor (Quantity_NOC_WHITE); + myNoShadingLight = new Graphic3d_LightSet(); + myNoShadingLight->Add (aLight); - myCurrLightSourceState = myStateCounter->Increment(); myMainSceneFbos[0] = new OpenGl_FrameBuffer(); myMainSceneFbos[1] = new OpenGl_FrameBuffer(); myMainSceneFbosOit[0] = new OpenGl_FrameBuffer(); diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index f9e01422f4..200f34baa9 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -280,10 +279,10 @@ public: Standard_EXPORT virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE; //! Returns list of lights of the view. - virtual const Graphic3d_ListOfCLight& Lights() const Standard_OVERRIDE { return myLights; } + virtual const Handle(Graphic3d_LightSet)& Lights() const Standard_OVERRIDE { return myLights; } //! Sets list of lights for the view. - virtual void SetLights (const Graphic3d_ListOfCLight& theLights) Standard_OVERRIDE + virtual void SetLights (const Handle(Graphic3d_LightSet)& theLights) Standard_OVERRIDE { myLights = theLights; myCurrLightSourceState = myStateCounter->Increment(); @@ -325,9 +324,6 @@ public: //! Returns list of OpenGL Z-layers. const OpenGl_LayerList& LayerList() const { return myZLayers; } - //! Returns list of openGL light sources. - const OpenGl_ListOfLight& LightList() const { return myLights; } - //! Returns OpenGL window implementation. const Handle(OpenGl_Window) GlWindow() const { return myWindow; } @@ -484,13 +480,14 @@ protected: Handle(Graphic3d_TextureEnv) myTextureEnvData; Graphic3d_GraduatedTrihedron myGTrihedronData; - OpenGl_ListOfLight myNoShadingLight; - OpenGl_ListOfLight myLights; + Handle(Graphic3d_LightSet) myNoShadingLight; + Handle(Graphic3d_LightSet) myLights; OpenGl_LayerList myZLayers; //!< main list of displayed structure, sorted by layers Graphic3d_WorldViewProjState myWorldViewProjState; //!< camera modification state OpenGl_StateCounter* myStateCounter; Standard_Size myCurrLightSourceState; + Standard_Size myLightsRevision; typedef std::pair StateInfo; diff --git a/src/OpenGl/OpenGl_View_Raytrace.cxx b/src/OpenGl/OpenGl_View_Raytrace.cxx index 04fcc20749..c8340b84be 100644 --- a/src/OpenGl/OpenGl_View_Raytrace.cxx +++ b/src/OpenGl/OpenGl_View_Raytrace.cxx @@ -42,24 +42,6 @@ namespace { static const OpenGl_Vec4 THE_WHITE_COLOR (1.0f, 1.0f, 1.0f, 1.0f); static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f); - - //! Operator returning TRUE for positional light sources. - struct IsLightPositional - { - bool operator() (const OpenGl_Light& theLight) - { - return theLight.Type != Graphic3d_TOLS_DIRECTIONAL; - } - }; - - //! Operator returning TRUE for any non-ambient light sources. - struct IsNotAmbient - { - bool operator() (const OpenGl_Light& theLight) - { - return theLight.Type != Graphic3d_TOLS_AMBIENT; - } - }; } namespace @@ -2491,68 +2473,75 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)& // ======================================================================= Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& theInvModelView, const Handle(OpenGl_Context)& theGlContext) { - std::vector aLightSources; - - if (myShadingModel != Graphic3d_TOSM_NONE) + std::vector aLightSources; + myRaytraceGeometry.Ambient = BVH_Vec4f (0.f, 0.f, 0.f, 0.f); + if (myShadingModel != Graphic3d_TOSM_NONE + && !myLights.IsNull()) { - aLightSources.assign (myLights.begin(), myLights.end()); + const Graphic3d_Vec4& anAmbient = myLights->AmbientColor(); + myRaytraceGeometry.Ambient = BVH_Vec4f (anAmbient.r(), anAmbient.g(), anAmbient.b(), 0.0f); // move positional light sources at the front of the list - std::partition (aLightSources.begin(), aLightSources.end(), IsLightPositional()); + aLightSources.reserve (myLights->Extent()); + for (Graphic3d_LightSet::Iterator aLightIter (myLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); + aLightIter.More(); aLightIter.Next()) + { + const Graphic3d_CLight& aLight = *aLightIter.Value(); + if (aLight.Type() != Graphic3d_TOLS_DIRECTIONAL) + { + aLightSources.push_back (aLightIter.Value()); + } + } + + for (Graphic3d_LightSet::Iterator aLightIter (myLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient); + aLightIter.More(); aLightIter.Next()) + { + if (aLightIter.Value()->Type() == Graphic3d_TOLS_DIRECTIONAL) + { + aLightSources.push_back (aLightIter.Value()); + } + } } // get number of 'real' (not ambient) light sources - const size_t aNbLights = std::count_if (aLightSources.begin(), aLightSources.end(), IsNotAmbient()); - + const size_t aNbLights = aLightSources.size(); Standard_Boolean wasUpdated = myRaytraceGeometry.Sources.size () != aNbLights; - if (wasUpdated) { myRaytraceGeometry.Sources.resize (aNbLights); } - myRaytraceGeometry.Ambient = BVH_Vec4f (0.f, 0.f, 0.f, 0.f); - for (size_t aLightIdx = 0, aRealIdx = 0; aLightIdx < aLightSources.size(); ++aLightIdx) { - const OpenGl_Light& aLight = aLightSources[aLightIdx]; - - if (aLight.Type == Graphic3d_TOLS_AMBIENT) - { - myRaytraceGeometry.Ambient += BVH_Vec4f (aLight.Color.r() * aLight.Intensity, - aLight.Color.g() * aLight.Intensity, - aLight.Color.b() * aLight.Intensity, - 0.0f); - continue; - } - - BVH_Vec4f aEmission (aLight.Color.r() * aLight.Intensity, - aLight.Color.g() * aLight.Intensity, - aLight.Color.b() * aLight.Intensity, + const Graphic3d_CLight& aLight = *aLightSources[aLightIdx]; + const Graphic3d_Vec4& aLightColor = aLight.PackedColor(); + BVH_Vec4f aEmission (aLightColor.r() * aLight.Intensity(), + aLightColor.g() * aLight.Intensity(), + aLightColor.b() * aLight.Intensity(), 1.0f); - BVH_Vec4f aPosition (-aLight.Direction.x(), - -aLight.Direction.y(), - -aLight.Direction.z(), + BVH_Vec4f aPosition (-aLight.PackedDirection().x(), + -aLight.PackedDirection().y(), + -aLight.PackedDirection().z(), 0.0f); - if (aLight.Type != Graphic3d_TOLS_DIRECTIONAL) + if (aLight.Type() != Graphic3d_TOLS_DIRECTIONAL) { - aPosition = BVH_Vec4f (static_cast(aLight.Position.x()), - static_cast(aLight.Position.y()), - static_cast(aLight.Position.z()), + aPosition = BVH_Vec4f (static_cast(aLight.Position().X()), + static_cast(aLight.Position().Y()), + static_cast(aLight.Position().Z()), 1.0f); // store smoothing radius in W-component - aEmission.w() = Max (aLight.Smoothness, 0.f); + aEmission.w() = Max (aLight.Smoothness(), 0.f); } else { // store cosine of smoothing angle in W-component - aEmission.w() = cosf (Min (Max (aLight.Smoothness, 0.f), static_cast (M_PI / 2.0))); + aEmission.w() = cosf (Min (Max (aLight.Smoothness(), 0.f), static_cast (M_PI / 2.0))); } - if (aLight.IsHeadlight) + if (aLight.IsHeadlight()) { aPosition = theInvModelView * aPosition; } diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index bc36fcc2d4..9899c81da3 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -883,10 +883,18 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection, myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio()); myBVHSelector.CacheClipPtsProjections(); - const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager(); - if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState) + const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager(); + const Handle(Graphic3d_LightSet)& aLights = myShadingModel == Graphic3d_TOSM_NONE ? myNoShadingLight : myLights; + Standard_Size aLightsRevision = 0; + if (!aLights.IsNull()) { - aManager->UpdateLightSourceStateTo (myShadingModel == Graphic3d_TOSM_NONE ? &myNoShadingLight : &myLights); + aLightsRevision = aLights->UpdateRevision(); + } + if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState + || aLightsRevision != myLightsRevision) + { + myLightsRevision = aLightsRevision; + aManager->UpdateLightSourceStateTo (aLights); myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()); } diff --git a/src/StdPrs/StdPrs_Plane.cxx b/src/StdPrs/StdPrs_Plane.cxx index 536c2c2566..4d93e570e4 100644 --- a/src/StdPrs/StdPrs_Plane.cxx +++ b/src/StdPrs/StdPrs_Plane.cxx @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/src/V3d/FILES b/src/V3d/FILES index 13db126437..bb363aad20 100755 --- a/src/V3d/FILES +++ b/src/V3d/FILES @@ -9,7 +9,6 @@ V3d_Coordinate.hxx V3d_DirectionalLight.cxx V3d_DirectionalLight.hxx V3d_ImageDumpOptions.hxx -V3d_Light.cxx V3d_Light.hxx V3d_ListOfLight.hxx V3d_ListOfView.hxx diff --git a/src/V3d/V3d.cxx b/src/V3d/V3d.cxx index 79d89c7e16..2e92a00caa 100644 --- a/src/V3d/V3d.cxx +++ b/src/V3d/V3d.cxx @@ -13,15 +13,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -// Modified 23/02/98 : FMN ; Remplacement PI par Standard_PI -// 02.15.100 : JR : Clutter -//-Version -//-Design -//-Warning -//-References -//-Language C++ 2.1 -//-Declarations -// for the class +#include #include #include @@ -31,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/src/V3d/V3d.hxx b/src/V3d/V3d.hxx index 0d227959bc..07672ea59b 100644 --- a/src/V3d/V3d.hxx +++ b/src/V3d/V3d.hxx @@ -17,13 +17,14 @@ #ifndef _V3d_HeaderFile #define _V3d_HeaderFile +#include #include #include #include - -#include #include +#include +class Graphic3d_Group; class V3d_View; //! This package contains the set of commands and services diff --git a/src/V3d/V3d_AmbientLight.cxx b/src/V3d/V3d_AmbientLight.cxx index 761711422d..3dc99869fe 100644 --- a/src/V3d/V3d_AmbientLight.cxx +++ b/src/V3d/V3d_AmbientLight.cxx @@ -13,11 +13,21 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -// Modified 30-03-98 : ZOV ; PRO6774 (reconstruction of the class hierarchy and suppressing useless methods) - #include -IMPLEMENT_STANDARD_RTTIEXT(V3d_AmbientLight,V3d_Light) +#include + +IMPLEMENT_STANDARD_RTTIEXT(V3d_AmbientLight, Graphic3d_CLight) + +// ======================================================================= +// function : V3d_AmbientLight +// purpose : +// ======================================================================= +V3d_AmbientLight::V3d_AmbientLight (const Quantity_Color& theColor) +: Graphic3d_CLight (Graphic3d_TOLS_AMBIENT) +{ + SetColor (theColor); +} // ======================================================================= // function : V3d_AmbientLight @@ -25,8 +35,11 @@ IMPLEMENT_STANDARD_RTTIEXT(V3d_AmbientLight,V3d_Light) // ======================================================================= V3d_AmbientLight::V3d_AmbientLight (const Handle(V3d_Viewer)& theViewer, const Quantity_Color& theColor) -: V3d_Light (theViewer) +: Graphic3d_CLight (Graphic3d_TOLS_AMBIENT) { - SetType (V3d_AMBIENT); SetColor (theColor); + if (!theViewer.IsNull()) + { + theViewer->AddLight (this); + } } diff --git a/src/V3d/V3d_AmbientLight.hxx b/src/V3d/V3d_AmbientLight.hxx index 72451eca31..eccc5a0124 100644 --- a/src/V3d/V3d_AmbientLight.hxx +++ b/src/V3d/V3d_AmbientLight.hxx @@ -20,21 +20,47 @@ #include class V3d_Viewer; -class V3d_AmbientLight; -DEFINE_STANDARD_HANDLE(V3d_AmbientLight, V3d_Light) //! Creation of an ambient light source in a viewer. -class V3d_AmbientLight : public V3d_Light +class V3d_AmbientLight : public Graphic3d_CLight { - + DEFINE_STANDARD_RTTIEXT(V3d_AmbientLight, Graphic3d_CLight) public: //! Constructs an ambient light source in the viewer. //! The default Color of this light source is WHITE. + Standard_EXPORT V3d_AmbientLight (const Quantity_Color& theColor = Quantity_NOC_WHITE); + + //! Constructs an ambient light source in the viewer. + //! The default Color of this light source is WHITE. + Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()") Standard_EXPORT V3d_AmbientLight (const Handle(V3d_Viewer)& theViewer, const Quantity_Color& theColor = Quantity_NOC_WHITE); - DEFINE_STANDARD_RTTIEXT(V3d_AmbientLight,V3d_Light) +//! @name hidden properties not applicable to ambient light +private: + + using Graphic3d_CLight::IsHeadlight; + using Graphic3d_CLight::Headlight; + using Graphic3d_CLight::SetHeadlight; + using Graphic3d_CLight::Position; + using Graphic3d_CLight::SetPosition; + using Graphic3d_CLight::ConstAttenuation; + using Graphic3d_CLight::LinearAttenuation; + using Graphic3d_CLight::Attenuation; + using Graphic3d_CLight::SetAttenuation; + using Graphic3d_CLight::Direction; + using Graphic3d_CLight::SetDirection; + using Graphic3d_CLight::Angle; + using Graphic3d_CLight::SetAngle; + using Graphic3d_CLight::Concentration; + using Graphic3d_CLight::SetConcentration; + using Graphic3d_CLight::Smoothness; + using Graphic3d_CLight::SetSmoothRadius; + using Graphic3d_CLight::SetSmoothAngle; + }; +DEFINE_STANDARD_HANDLE(V3d_AmbientLight, Graphic3d_CLight) + #endif // _V3d_AmbientLight_HeaderFile diff --git a/src/V3d/V3d_DirectionalLight.cxx b/src/V3d/V3d_DirectionalLight.cxx index c7ba0418c5..69aac382fa 100644 --- a/src/V3d/V3d_DirectionalLight.cxx +++ b/src/V3d/V3d_DirectionalLight.cxx @@ -13,18 +13,38 @@ #include -#include -#include -#include -#include -#include #include -#include -#include -#include IMPLEMENT_STANDARD_RTTIEXT(V3d_DirectionalLight,V3d_PositionLight) +// ======================================================================= +// function : V3d_DirectionalLight +// purpose : +// ======================================================================= +V3d_DirectionalLight::V3d_DirectionalLight (const V3d_TypeOfOrientation theDirection, + const Quantity_Color& theColor, + const Standard_Boolean theIsHeadlight) +: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, Handle(V3d_Viewer)()) +{ + SetColor (theColor); + SetHeadlight (theIsHeadlight); + SetDirection (V3d::GetProjAxis (theDirection)); +} + +// ======================================================================= +// function : V3d_DirectionalLight +// purpose : +// ======================================================================= +V3d_DirectionalLight::V3d_DirectionalLight (const gp_Dir& theDirection, + const Quantity_Color& theColor, + const Standard_Boolean theIsHeadlight) +: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, Handle(V3d_Viewer)()) +{ + SetColor (theColor); + SetHeadlight (theIsHeadlight); + SetDirection (theDirection); +} + // ======================================================================= // function : V3d_DirectionalLight // purpose : @@ -33,16 +53,11 @@ V3d_DirectionalLight::V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfOrientation theDirection, const Quantity_Color& theColor, const Standard_Boolean theIsHeadlight) -: V3d_PositionLight (theViewer) +: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, theViewer) { - gp_Dir aV = V3d::GetProjAxis (theDirection); - SetType (V3d_DIRECTIONAL); SetColor (theColor); SetHeadlight (theIsHeadlight); - SetTarget (0., 0., 0.); - SetPosition (-aV.X(), -aV.Y(), -aV.Z()); - SetSmoothAngle (0.2); - SetIntensity (20.0); + SetDirection (V3d::GetProjAxis (theDirection)); } // ======================================================================= @@ -58,25 +73,11 @@ V3d_DirectionalLight::V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theZp, const Quantity_Color& theColor, const Standard_Boolean theIsHeadlight) -: V3d_PositionLight (theViewer) +: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, theViewer) { - SetType (V3d_DIRECTIONAL); SetColor (theColor); SetHeadlight (theIsHeadlight); - SetTarget (theXt, theYt, theZt); - SetPosition (theXp, theYp, theZp); -} - -// ======================================================================= -// function : SetSmoothAngle -// purpose : -// ======================================================================= -void V3d_DirectionalLight::SetSmoothAngle (const Standard_Real theValue) -{ - V3d_BadValue_Raise_if (theValue < 0.0 || theValue > M_PI / 2.0, - "Bad value for smoothing angle"); - - myLight.Smoothness = static_cast (theValue); + SetDirection (gp_Dir (gp_XYZ (theXt, theYt, theZt) - gp_XYZ(theXp, theYp, theZp))); } // ======================================================================= @@ -85,213 +86,5 @@ void V3d_DirectionalLight::SetSmoothAngle (const Standard_Real theValue) // ======================================================================= void V3d_DirectionalLight::SetDirection (V3d_TypeOfOrientation theDirection) { - gp_Dir aV = V3d::GetProjAxis (theDirection); - SetDirection (aV.X(), aV.Y(), aV.Z()); -} - -// ======================================================================= -// function : SetDirection -// purpose : -// ======================================================================= -void V3d_DirectionalLight::SetDirection (Standard_Real theVx, - Standard_Real theVy, - Standard_Real theVz) -{ - gp_Dir aV (theVx, theVy, theVz); - myLight.Direction.x() = static_cast (aV.X()); - myLight.Direction.y() = static_cast (aV.Y()); - myLight.Direction.z() = static_cast (aV.Z()); -} - -// ======================================================================= -// function : SetDisplayPosition -// purpose : -// ======================================================================= -void V3d_DirectionalLight::SetDisplayPosition (Standard_Real theX, - Standard_Real theY, - Standard_Real theZ) -{ - myDisplayPosition.SetCoord(theX, theY, theZ); - - gp_XYZ aTarget; - Target (aTarget.ChangeCoord (1), aTarget.ChangeCoord (2), aTarget.ChangeCoord (3)); - - const gp_XYZ aDispPos = aTarget - gp_XYZ(theX, theY, theZ); - if (aDispPos.Modulus() > gp::Resolution()) - { - SetDirection (aDispPos.X(), aDispPos.Y(), aDispPos.Z()); - } -} - -// ======================================================================= -// function : DisplayPosition -// purpose : -// ======================================================================= -void V3d_DirectionalLight::Symbol (const Handle(Graphic3d_Group)& theSymbol, const Handle(V3d_View)& theView) const -{ - Standard_Real Xi,Yi,Zi,Xf,Yf,Zf,Rayon,PXT,PYT,X,Y,Z,XT,YT,ZT; - Standard_Real A,B,C,Dist,Beta,CosBeta,SinBeta,Coef,X1,Y1,Z1; - Standard_Real DX,DY,DZ,VX,VY,VZ; - Standard_Integer IXP,IYP,j; - TColStd_Array2OfReal MatRot(0,2,0,2); - - theView->Proj(VX,VY,VZ); - this->DisplayPosition(Xi,Yi,Zi); - Rayon = this->Radius(); - theView->Project(Xi,Yi,Zi,PXT,PYT); - theView->Convert(PXT,PYT,IXP,IYP); -// Coordinated 3d in the plane of projection of the source. - theView->Convert(IXP,IYP,XT,YT,ZT); - theView->Convert(PXT,PYT+Rayon,IXP,IYP); - theView->Convert(IXP,IYP,X,Y,Z); - X = X+Xi-XT; Y = Y+Yi-YT; Z = Z+Zi-ZT; - Dist = Sqrt( Square(X-Xi) + Square(Y-Yi) + Square(Z-Zi) ); -// Axis of rotation. - A = (X-Xi)/Dist; - B = (Y-Yi)/Dist; - C = (Z-Zi)/Dist; - -// A sphere is drawn - V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.); - for( j=1 ; j<=3 ; j++ ) { - Beta = j * M_PI / 4.; - CosBeta = Cos(Beta); - SinBeta = Sin(Beta); - Coef = 1. - CosBeta; - MatRot(0,0) = A * A + (1. - A * A) * CosBeta; - MatRot(0,1) = -C * SinBeta + Coef * A * B; - MatRot(0,2) = B * SinBeta + Coef * A * C; - MatRot(1,0) = C * SinBeta + Coef * A * B; - MatRot(1,1) = B * B + (1. - B * B) * CosBeta; - MatRot(1,2) = -A * SinBeta + Coef * B * C; - MatRot(2,0) = -B * SinBeta + Coef * A * C; - MatRot(2,1) = A * SinBeta + Coef * B * C; - MatRot(2,2) = C * C + (1. - C * C) * CosBeta; - Xf = Xi * MatRot(0,0) + Yi * MatRot(0,1) + Zi * MatRot(0,2); - Yf = Xi * MatRot(1,0) + Yi * MatRot(1,1) + Zi * MatRot(1,2); - Zf = Xi * MatRot(2,0) + Yi * MatRot(2,1) + Zi * MatRot(2,2); -// Rotation of the normal - X1 = VX * MatRot(0,0) + VY * MatRot(0,1) + VZ * MatRot(0,2); - Y1 = VX * MatRot(1,0) + VY * MatRot(1,1) + VZ * MatRot(1,2); - Z1 = VX * MatRot(2,0) + VY * MatRot(2,1) + VZ * MatRot(2,2); - VX = X1 + Xi - Xf ; VY = Y1 + Yi - Yf ; VZ = Z1 + Zi - Zf; - V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.); - } - -// The arrow is drawn - Rayon = this->Radius(); - this->Direction(DX,DY,DZ); - X = Xi + DX*Rayon/10.; Y = Yi + DY*Rayon/10.; Z = Zi + DZ*Rayon/10.; - - Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2); - aPrims->AddVertex(Standard_ShortReal(Xi),Standard_ShortReal(Yi),Standard_ShortReal(Zi)); - aPrims->AddVertex(Standard_ShortReal(X),Standard_ShortReal(Y),Standard_ShortReal(Z)); - theSymbol->AddPrimitiveArray(aPrims); - - V3d::ArrowOfRadius(theSymbol, X, Y, Z, DX, DY, DZ, M_PI / 15., Rayon / 20.); -} - -// ======================================================================= -// function : Display -// purpose : -// ======================================================================= -void V3d_DirectionalLight::Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theTPres) -{ - Standard_Real X,Y,Z,Rayon; - Standard_Real X0,Y0,Z0,VX,VY,VZ; - Standard_Real X1,Y1,Z1; - Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini; - V3d_TypeOfRepresentation Pres; - -// Creation of a structure of markable elements (position of the -// light, and the domain of lighting represented by a circle) -// Creation of a structure of non-markable elements (target, meridian and -// parallel). - - Pres = theTPres; - Handle(V3d_Viewer) TheViewer = theView->Viewer(); - if (!myGraphicStructure.IsNull()) { - myGraphicStructure->Disconnect(myGraphicStructure1); - myGraphicStructure->Clear(); - myGraphicStructure1->Clear(); - if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation; - } - else { - if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE; - Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure = slight; - Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure1 = snopick; - } - - Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup(); - Handle(Graphic3d_Group) gsphere; - if (Pres == V3d_COMPLETE - || Pres == V3d_PARTIAL) - { - gsphere = myGraphicStructure->NewGroup(); - } - - Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup(); - - X0 = myTarget.X(); - Y0 = myTarget.Y(); - Z0 = myTarget.Z(); - -//Display of the position of the light. - - const Quantity_Color Col1 = this->Color(); - Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d(); - Asp1->SetColor(Col1); - glight->SetPrimitivesAspect(Asp1); - this->Symbol(glight,theView); - - // Display of the markable sphere (limit at the circle). - - if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) { - - Rayon = this->Radius(); - theView->Proj(VX,VY,VZ); - V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon); - -//Display of the meridian - - Quantity_Color Col2(Quantity_NOC_GREEN); - Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d - (Col2,Aspect_TOL_SOLID,1.); - gnopick->SetPrimitivesAspect(Asp2); - -// Definition of the axis of circle - theView->Up(DXRef,DYRef,DZRef); - this->DisplayPosition(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - -// Display of the parallel - -// Definition of the axis of circle - theView->Proj(VX,VY,VZ); - theView->Up(X1,Y1,Z1); - DXRef = VY * Z1 - VZ * Y1; - DYRef = VZ * X1 - VX * Z1; - DZRef = VX * Y1 - VY * X1; - this->DisplayPosition(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - - } - - myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT); -// cout << "MyGraphicStructure exploration \n" << flush; MyGraphicStructure->Exploration(); - myTypeOfRepresentation = Pres; - myGraphicStructure->Display(); + SetDirection (V3d::GetProjAxis (theDirection)); } diff --git a/src/V3d/V3d_DirectionalLight.hxx b/src/V3d/V3d_DirectionalLight.hxx index 435de0852b..30215cc9c3 100644 --- a/src/V3d/V3d_DirectionalLight.hxx +++ b/src/V3d/V3d_DirectionalLight.hxx @@ -20,16 +20,29 @@ #include #include -class V3d_Viewer; -class V3d_DirectionalLight; -DEFINE_STANDARD_HANDLE(V3d_DirectionalLight, V3d_PositionLight) - //! Directional light source for a viewer. class V3d_DirectionalLight : public V3d_PositionLight { + DEFINE_STANDARD_RTTIEXT(V3d_DirectionalLight, V3d_PositionLight) public: //! Creates a directional light source in the viewer. + Standard_EXPORT V3d_DirectionalLight (const V3d_TypeOfOrientation theDirection = V3d_XposYposZpos, + const Quantity_Color& theColor = Quantity_NOC_WHITE, + const Standard_Boolean theIsHeadlight = Standard_False); + + //! Creates a directional light source in the viewer. + Standard_EXPORT V3d_DirectionalLight (const gp_Dir& theDirection, + const Quantity_Color& theColor = Quantity_NOC_WHITE, + const Standard_Boolean theIsHeadlight = Standard_False); + + //! Defines the direction of the light source by a predefined orientation. + Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theDirection); + using Graphic3d_CLight::SetDirection; + +public: + + Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()") Standard_EXPORT V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer, const V3d_TypeOfOrientation theDirection = V3d_XposYposZpos, const Quantity_Color& theColor = Quantity_NOC_WHITE, @@ -39,6 +52,7 @@ public: //! theXt, theYt, theZt : Coordinate of light source Target. //! theXp, theYp, theZp : Coordinate of light source Position. //! The others parameters describe before. + Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()") Standard_EXPORT V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theXt, const Standard_Real theYt, @@ -49,71 +63,22 @@ public: const Quantity_Color& theColor = Quantity_NOC_WHITE, const Standard_Boolean theIsHeadlight = Standard_False); - //! Defines the direction of the light source by a predefined orientation. - Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theDirection); - - //! Defines the direction of the light source by the predefined vector theXm, theYm, theZm. - //! Warning: raises BadValue from V3d if the vector is null. - Standard_EXPORT void SetDirection (Standard_Real theXm, - Standard_Real theYm, - Standard_Real theZm); - - //! Defines the point of light source representation. - Standard_EXPORT void SetDisplayPosition (Standard_Real theX, - Standard_Real theY, - Standard_Real theZ); - - //! Calls SetDisplayPosition method. - virtual void SetPosition (Standard_Real theXp, - Standard_Real theYp, - Standard_Real theZp) Standard_OVERRIDE { SetDisplayPosition (theXp, theYp, theZp); } - - //! Modifies the smoothing angle (in radians) - Standard_EXPORT void SetSmoothAngle (const Standard_Real theValue); - - //! Display the graphic structure of light source - //! in the chosen view. We have three type of representation - //! - SIMPLE : Only the light source is displayed. - //! - PARTIAL : The light source and the light space are - //! displayed. - //! - COMPLETE : The same representation as PARTIAL. - //! We can choose the "SAMELAST" as parameter of representation - //! In this case the graphic structure representation will be - //! the last displayed. - Standard_EXPORT void Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theRepresentation) Standard_OVERRIDE; - - //! Calls DisplayPosition method. - virtual void Position (Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const Standard_OVERRIDE { DisplayPosition (theX, theY, theZ); } - - //! Returns the chosen position to represent the light source. - void DisplayPosition (Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const { myDisplayPosition.Coord (theX, theY, theZ); } - - //! Returns the theVx, theVy, theVz direction of the light source. - void Direction (Standard_Real& theVx, - Standard_Real& theVy, - Standard_Real& theVz) const - { - theVx = myLight.Direction.x(); - theVy = myLight.Direction.y(); - theVz = myLight.Direction.z(); - } - - DEFINE_STANDARD_RTTIEXT(V3d_DirectionalLight,V3d_PositionLight) - +//! @name hidden properties not applicable to directional light private: - //! Defines the representation of the directional light source. - Standard_EXPORT void Symbol (const Handle(Graphic3d_Group)& theSymbol, - const Handle(V3d_View)& theView) const Standard_OVERRIDE; + using Graphic3d_CLight::Position; + using Graphic3d_CLight::SetPosition; + using Graphic3d_CLight::ConstAttenuation; + using Graphic3d_CLight::LinearAttenuation; + using Graphic3d_CLight::Attenuation; + using Graphic3d_CLight::SetAttenuation; + using Graphic3d_CLight::Angle; + using Graphic3d_CLight::SetAngle; + using Graphic3d_CLight::Concentration; + using Graphic3d_CLight::SetConcentration; -private: - - gp_Pnt myDisplayPosition; }; +DEFINE_STANDARD_HANDLE(V3d_DirectionalLight, V3d_PositionLight) + #endif // _V3d_DirectionalLight_HeaderFile diff --git a/src/V3d/V3d_Light.cxx b/src/V3d/V3d_Light.cxx deleted file mode 100644 index b4ac19ae0f..0000000000 --- a/src/V3d/V3d_Light.cxx +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -/*********************************************************************** - FONCTION : - ---------- - Classe V3d_SpotLight : - HISTORIQUE DES MODIFICATIONS : - -------------------------------- - 00-09-92 : GG ; Creation. -************************************************************************/ -/*----------------------------------------------------------------------*/ -/* - * Includes - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -IMPLEMENT_STANDARD_RTTIEXT(V3d_Light,Standard_Transient) - -// ======================================================================= -// function : V3d_Light -// purpose : -// ======================================================================= -V3d_Light::V3d_Light (const Handle(V3d_Viewer)& theViewer) -{ - SetType (V3d_AMBIENT); - theViewer->AddLight (this); -} - -// ======================================================================= -// function : SetType -// purpose : -// ======================================================================= -void V3d_Light::SetType (const V3d_TypeOfLight theType) -{ - myLight.Type = (Graphic3d_TypeOfLightSource)theType; -} - -// ======================================================================= -// function : SetColor -// purpose : -// ======================================================================= -void V3d_Light::SetColor (const Quantity_Color& theColor) -{ - myLight.Color.r() = static_cast (theColor.Red()); - myLight.Color.g() = static_cast (theColor.Green()); - myLight.Color.b() = static_cast (theColor.Blue()); -} - -// ======================================================================= -// function : Type -// purpose : -// ======================================================================= -V3d_TypeOfLight V3d_Light::Type() const -{ - return (V3d_TypeOfLight)myLight.Type; -} - -// ======================================================================= -// function : SetIntensity -// purpose : -// ======================================================================= -void V3d_Light::SetIntensity (const Standard_Real theValue) -{ - Standard_ASSERT_RAISE (theValue > 0., - "V3d_Light::SetIntensity, " - "Negative value for intensity"); - - myLight.Intensity = static_cast (theValue); -} - -// ======================================================================= -// function : Intensity -// purpose : -// ======================================================================= -Standard_Real V3d_Light::Intensity() const -{ - return myLight.Intensity; -} - -// ======================================================================= -// function : Smoothness -// purpose : -// ======================================================================= -Standard_Real V3d_Light::Smoothness() const -{ - return myLight.Smoothness; -} - -// ======================================================================= -// function : Headlight -// purpose : -// ======================================================================= -Standard_Boolean V3d_Light::Headlight() const -{ - return myLight.IsHeadlight; -} - -// ======================================================================= -// function : SetHeadlight -// purpose : -// ======================================================================= -void V3d_Light::SetHeadlight (const Standard_Boolean theValue) -{ - myLight.IsHeadlight = theValue; -} - -// ======================================================================= -// function : SymetricPointOnSphere -// purpose : -// ======================================================================= -void V3d_Light::SymetricPointOnSphere (const Handle(V3d_View)& aView, - const gp_Pnt& Center, - const gp_Pnt& aPoint, - const Standard_Real Rayon, - Standard_Real& X, Standard_Real& Y, Standard_Real& Z, - Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ ) -{ - Standard_Real X0,Y0,Z0,XP,YP,ZP; - Standard_Real PXP,PYP,DeltaX,DeltaY,DeltaZ; - Standard_Real A,B,C,Delta,Lambda; - Standard_Integer IPX,IPY; - - Center.Coord(X0,Y0,Z0); - aPoint.Coord(XP,YP,ZP); - aView->Project(XP,YP,ZP,PXP,PYP); - aView->Convert(PXP,PYP,IPX,IPY); - aView->ProjReferenceAxe(IPX,IPY,X,Y,Z,VX,VY,VZ); - DeltaX = X0 - XP; - DeltaY = Y0 - YP; - DeltaZ = Z0 - ZP; - -// The point of intersection of straight lines defined by : -// - Straight line passing by the point of projection and the eye -// if this is a perspective, parralel to the normal of the view -// if this is an axonometric view. -// position in the view is parallel to the normal of the view -// - The distance position of the target camera is equal to the radius. - - A = VX*VX + VY*VY + VZ*VZ ; - B = -2. * (VX*DeltaX + VY*DeltaY + VZ*DeltaZ); - C = DeltaX*DeltaX + DeltaY*DeltaY + DeltaZ*DeltaZ - - Rayon*Rayon ; - Delta = B*B - 4.*A*C; - if ( Delta >= 0 ) { - Lambda = (-B + Sqrt(Delta))/(2.*A); - if ( Lambda >= -0.0001 && Lambda <= 0.0001 ) - Lambda = (-B - Sqrt(Delta))/(2.*A); - X = XP + Lambda*VX; - Y = YP + Lambda*VY; - Z = ZP + Lambda*VZ; - } - else { - X = XP; Y = YP; Z = ZP; - } -} - -// ======================================================================= -// function : IsDisplayed -// purpose : -// ======================================================================= -Standard_Boolean V3d_Light::IsDisplayed() const -{ - if (myGraphicStructure.IsNull()) - { - return Standard_False; - } - - return myGraphicStructure->IsDisplayed(); -} diff --git a/src/V3d/V3d_Light.hxx b/src/V3d/V3d_Light.hxx index 5b1fa556de..26ef7c4fc1 100644 --- a/src/V3d/V3d_Light.hxx +++ b/src/V3d/V3d_Light.hxx @@ -19,81 +19,8 @@ #include #include -#include -class Graphic3d_Structure; -class V3d_Viewer; - -class V3d_Light; -DEFINE_STANDARD_HANDLE(V3d_Light, Standard_Transient) - -//! Defines services on Light type objects.. -//! (base class for AmbientLight and PositionLight) -class V3d_Light : public Standard_Transient -{ -public: - - //! Defines the color of a light source by giving the basic color. - Standard_EXPORT void SetColor (const Quantity_Color& theColor); - - //! Returns the color of the light source. - Quantity_Color Color() const { return Quantity_Color (myLight.Color.rgb()); } - - //! Returns the Type of the Light - Standard_EXPORT V3d_TypeOfLight Type() const; - - //! returns true if the light is a headlight - Standard_EXPORT Standard_Boolean Headlight() const; - - //! Setup headlight flag. - Standard_EXPORT void SetHeadlight (const Standard_Boolean theValue); - - //! Modifies the intensity of light source. - Standard_EXPORT void SetIntensity (const Standard_Real theValue); - - //! returns the intensity of light source - Standard_EXPORT Standard_Real Intensity() const; - - //! returns the smoothness of light source - Standard_EXPORT Standard_Real Smoothness() const; - - //! Returns TRUE when a light representation is displayed - Standard_EXPORT Standard_Boolean IsDisplayed() const; - -friend - //! Updates the lights of the view. The view is redrawn. - Standard_EXPORT void V3d_View::UpdateLights() const; - - DEFINE_STANDARD_RTTIEXT(V3d_Light,Standard_Transient) - -protected: - - Standard_EXPORT V3d_Light (const Handle(V3d_Viewer)& theViewer); - - //! Sets type of the light. - Standard_EXPORT void SetType (const V3d_TypeOfLight theType); - - //! Returns the symmetric point coordinates of "aPoint" - //! on the sphere of center "Center" and radius "Radius". - //! VX,VY,VZ is the project vector of view. - Standard_EXPORT static void SymetricPointOnSphere (const Handle(V3d_View)& aView, - const gp_Pnt& Center, - const gp_Pnt& aPoint, - const Standard_Real Radius, - Standard_Real& X, Standard_Real& Y, Standard_Real& Z, - Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ); - -protected: - - //! Return light properties associated to this light source. - //! Hidden method exposed only to V3d_View. - Standard_EXPORT const Graphic3d_CLight& Light() const { return myLight; } - -protected: - - Graphic3d_CLight myLight; - Handle(Graphic3d_Structure) myGraphicStructure; - Handle(Graphic3d_Structure) myGraphicStructure1; -}; +typedef Graphic3d_CLight V3d_Light; +typedef Handle_Graphic3d_CLight Handle_V3d_Light; #endif // _V3d_Light_HeaderFile diff --git a/src/V3d/V3d_ListOfLight.hxx b/src/V3d/V3d_ListOfLight.hxx index f314aea8f1..a8ececa755 100644 --- a/src/V3d/V3d_ListOfLight.hxx +++ b/src/V3d/V3d_ListOfLight.hxx @@ -14,11 +14,9 @@ #ifndef _V3d_ListOfLight_HeaderFile #define _V3d_ListOfLight_HeaderFile -class V3d_Light; -#include -#include +#include -typedef NCollection_List V3d_ListOfLight; +typedef NCollection_List V3d_ListOfLight; typedef V3d_ListOfLight::Iterator V3d_ListOfLightIterator; #endif // _V3d_ListOfLight_HeaderFile diff --git a/src/V3d/V3d_PositionLight.cxx b/src/V3d/V3d_PositionLight.cxx index 3e2eab1f64..fae0432234 100644 --- a/src/V3d/V3d_PositionLight.cxx +++ b/src/V3d/V3d_PositionLight.cxx @@ -13,424 +13,20 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -IMPLEMENT_STANDARD_RTTIEXT(V3d_PositionLight,V3d_Light) +IMPLEMENT_STANDARD_RTTIEXT(V3d_PositionLight, Graphic3d_CLight) // ======================================================================= // function : V3d_PositionLight // purpose : // ======================================================================= -V3d_PositionLight::V3d_PositionLight (const Handle(V3d_Viewer)& theViewer) -: V3d_Light(theViewer) +V3d_PositionLight::V3d_PositionLight (Graphic3d_TypeOfLightSource theType, + const Handle(V3d_Viewer)& theViewer) +: Graphic3d_CLight (theType) { -} - -// ======================================================================= -// function : SetTarget -// purpose : -// ======================================================================= -void V3d_PositionLight::SetTarget (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ) -{ - Standard_Real Xc,Yc,Zc, Xp,Yp,Zp; - - // Recalculation of the position - myTarget.Coord(Xc,Yc,Zc); - Position (Xp,Yp,Zp) ; - - Xp = Xp + (theX - Xc); - Yp = Yp + (theY - Yc); - Zp = Zp + (theZ - Zc); - - // Affectation - myTarget.SetCoord(theX,theY,theZ); - SetPosition(Xp,Yp,Zp) ; -} - -// ======================================================================= -// function : SetRadius -// purpose : -// ======================================================================= -void V3d_PositionLight::SetRadius (const Standard_Real theRadius) -{ - V3d_BadValue_Raise_if( theRadius <= 0. , "V3d_PositionLight::SetRadius, bad radius"); - V3d_BadValue_Raise_if( Type() == V3d_DIRECTIONAL , "V3d_PositionLight::SetRadius, bad light type"); - - // The target point remains unchanged, only the position of the light is modified by preserving the direction - gp_XYZ aPosOld; - Position (aPosOld.ChangeCoord (1), aPosOld.ChangeCoord (2), aPosOld.ChangeCoord (3)); - gp_XYZ aDir = aPosOld - myTarget.XYZ(); - aDir.Normalize(); - - const gp_XYZ aPosNew = myTarget.XYZ() + aDir * theRadius; - SetPosition (aPosNew.X(), aPosNew.Y(), aPosNew.Z()); -} - -// ======================================================================= -// function : OnHideFace -// purpose : -// ======================================================================= -void V3d_PositionLight::OnHideFace (const Handle(V3d_View)& theView) -{ - Standard_Real Xp,Yp,Zp, X,Y,Z, VX,VY,VZ; - - Position (Xp,Yp,Zp); - V3d_Light::SymetricPointOnSphere (theView, myTarget, gp_Pnt(Xp,Yp,Yp), Radius(), X,Y,Z, VX,VY,VZ); - - // This is a visible point - if ((VX*(X-Xp) < 0.) && (VY*(Y-Yp) < 0.) && (VZ*(Z-Zp) < 0.)) - SetPosition (X,Y,Z); -} - -// ======================================================================= -// function : OnSeeFace -// purpose : -// ======================================================================= -void V3d_PositionLight::OnSeeFace (const Handle(V3d_View)& theView) -{ - Standard_Real Xp,Yp,Zp, X,Y,Z, VX,VY,VZ; - - Position (Xp,Yp,Zp); - V3d_Light::SymetricPointOnSphere (theView, myTarget, gp_Pnt(Xp,Yp,Yp), Radius(), X,Y,Z, VX,VY,VZ); - - // This is a hidden point - if ((VX*(X-Xp) > 0.) && (VY*(Y-Yp) > 0.) && (VZ*(Z-Zp) > 0.)) - SetPosition (X,Y,Z); -} - -// ======================================================================= -// function : SeeOrHide -// purpose : -// ======================================================================= -Standard_Boolean V3d_PositionLight::SeeOrHide (const Handle(V3d_View)& theView) const -{ - Standard_Real Xp,Yp,Zp, X,Y,Z, VX,VY,VZ; - - Position (Xp,Yp,Zp); - V3d_Light::SymetricPointOnSphere (theView, myTarget, gp_Pnt(Xp,Yp,Yp), Radius(), X,Y,Z, VX,VY,VZ); - - // Is it a visible or a hidden point - return ( (VX*(X-Xp) > 0.) || (VY*(Y-Yp) > 0.) || (VZ*(Z-Zp) > 0.) )? - // the source is on the hidden face - Standard_False: - // the source is on the visible face. - Standard_True; -} - -// ======================================================================= -// function : Display -// purpose : -// ======================================================================= -void V3d_PositionLight::Display (const Handle(V3d_View)& theView, const V3d_TypeOfRepresentation theTPres) -{ - Graphic3d_Vertex PText ; - Standard_Real X,Y,Z,Rayon; - Standard_Real X0,Y0,Z0,VX,VY,VZ; - Standard_Real X1,Y1,Z1; - Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini; - V3d_TypeOfRepresentation Pres; - -// Creation of a structure of markable elements (position of the -// light, and the domain of lighting represented by a circle) -// Creation of a structure snopick of non-markable elements (target, meridian and -// parallel). - - Pres = theTPres; - Handle(V3d_Viewer) TheViewer = theView->Viewer(); - if (!myGraphicStructure.IsNull()) { - myGraphicStructure->Disconnect(myGraphicStructure1); - myGraphicStructure->Clear(); - myGraphicStructure1->Clear(); - if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation; - } - else { - if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE; - Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure = slight; - Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure1 = snopick; - } - - Handle(Graphic3d_Group) gradius, gExtArrow, gIntArrow; - if (Type() != V3d_DIRECTIONAL - && Pres == V3d_COMPLETE) + if (!theViewer.IsNull()) { - gradius = myGraphicStructure->NewGroup(); - gExtArrow = myGraphicStructure->NewGroup(); - gIntArrow = myGraphicStructure->NewGroup(); - } - Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup(); - Handle(Graphic3d_Group) gsphere; - if (Pres == V3d_COMPLETE - || Pres == V3d_PARTIAL) - { - gsphere = myGraphicStructure->NewGroup(); - } - - Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup(); - - X0 = myTarget.X(); - Y0 = myTarget.Y(); - Z0 = myTarget.Z(); - -// Display of the light position. - - const Quantity_Color Col1 = this->Color(); - Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d(); - Asp1->SetColor(Col1); - glight->SetPrimitivesAspect(Asp1); - this->Symbol(glight,theView); - -// Display of the marking sphere (limit at the circle). - - if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) { - - Rayon = this->Radius(); - theView->Proj(VX,VY,VZ); - V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon); - - if (Type() != V3d_DIRECTIONAL) { - - //Display of the radius of the sphere (line + text) - - if (Pres == V3d_COMPLETE) { - this->Position(X,Y,Z); - Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2); - aPrims->AddVertex(X0,Y0,Z0); - aPrims->AddVertex(X,Y,Z); - gnopick->AddPrimitiveArray(aPrims); - V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.); - V3d::ArrowOfRadius(gIntArrow,X0,Y0,Z0,X0-X,Y0-Y,Z0-Z,M_PI/15.,Rayon/20.); - TCollection_AsciiString ValOfRadius(Rayon); - PText.SetCoord( .5*(X0+X), .5*(Y0+Y), .5*(Z0+Z) ); - gradius->Text(ValOfRadius.ToCString(),PText,0.01); - } - } - - // Display of the meridian - - Quantity_Color Col2(Quantity_NOC_GREEN); - Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.); - gnopick->SetPrimitivesAspect(Asp2); - - // Definition of the axis of circle - theView->Up(DXRef,DYRef,DZRef); - this->Position(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - - // Display of the parallel - - // Definition of the axis of circle - theView->Proj(VX,VY,VZ); - theView->Up(X1,Y1,Z1); - DXRef = VY * Z1 - VZ * Y1; - DYRef = VZ * X1 - VX * Z1; - DZRef = VX * Y1 - VY * X1; - this->Position(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - } - - myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT); - myTypeOfRepresentation = Pres; - myGraphicStructure->Display(); -} - -// ======================================================================= -// function : Display -// purpose : -// ======================================================================= -void V3d_PositionLight::Tracking (const Handle(V3d_View)& theView, - const V3d_TypeOfPickLight theWhatPick, - const Standard_Integer theXpix, - const Standard_Integer theYpix) -{ - Standard_Real XPp,YPp,PXT,PYT,X,Y,Z,Rayon,Ylim; - Standard_Real XMinTrack,XMaxTrack,YMinTrack,YMaxTrack; - Standard_Real XT,YT,ZT,X0,Y0,Z0,XP,YP,ZP,VX,VY,VZ,A,B,C,Delta; - Standard_Real DX,DY,PXP,PYP,Xproj,Yproj; - Standard_Real A1,A2,B1,B2,Rap,OldRprj,NewRprj; - Standard_Real Xi,Yi,Zi,DeltaX,DeltaY,DeltaZ,Lambda; - Standard_Integer IPX,IPY; - - theView->Convert(theXpix,theYpix,XPp,YPp); - X0 = myTarget.X(); - Y0 = myTarget.Y(); - Z0 = myTarget.Z(); - theView->Project(X0,Y0,Z0,PXT,PYT); - theView->Convert(PXT,PYT,IPX,IPY); -// Coord 3d in the plane of projection of the target. - theView->Convert(IPX,IPY,XT,YT,ZT); - switch (theWhatPick) { - case V3d_POSITIONLIGHT : - // The Coordinates should remain inside of the sphere - Rayon = Radius(); - XMinTrack = PXT - Rayon; - XMaxTrack = PXT + Rayon; - Ylim = Sqrt( Square(Rayon) - Square(XPp - PXT) ); - YMinTrack = PYT - Ylim; - YMaxTrack = PYT + Ylim; - if (XPp >= XMinTrack && XPp <= XMaxTrack) { - if (YPp >= YMinTrack && YPp <= YMaxTrack) { - theView->ProjReferenceAxe(theXpix,theYpix,XP,YP,ZP,VX,VY,VZ); - DeltaX = X0 - XP; - DeltaY = Y0 - YP; - DeltaZ = Z0 - ZP; - -// The point of intersection of straight lines defined by : -// - Straight line passing by the point of projection and the eye -// if this is a perspective, parralel to the normal of the view -// if this is an axonometric view. -// position in the view is parallel to the normal of the view -// - The distance position of the target camera is equal to the radius. - - A = VX*VX + VY*VY + VZ*VZ ; - B = -2. * (VX*DeltaX + VY*DeltaY + VZ*DeltaZ); - C = DeltaX*DeltaX + DeltaY*DeltaY + DeltaZ*DeltaZ - - Rayon*Rayon ; - Delta = B*B - 4.*A*C; - if ( Delta >= 0 ) { - Lambda = (-B + Sqrt(Delta))/(2.*A); - X = XP + Lambda*VX; - Y = YP + Lambda*VY; - Z = ZP + Lambda*VZ; - SetPosition(X,Y,Z); - - if (Type() == V3d_SPOT) - ((V3d_SpotLight*)this)->SetDirection(X0-X,Y0-Y,Z0-Z); - - Display(theView,myTypeOfRepresentation); - (theView->Viewer())->UpdateLights(); - } - } - } - break; - - case V3d_SPACELIGHT : - theView->Convert(PXT,PYT,IPX,IPY); -// In this case Xpix,Ypix correspond to a distance, relative -// to the translation that is planned to be performed on the sphere. - theView->Convert(IPX+theXpix,IPY+theYpix,X,Y,Z); - X = X+X0-XT; - Y = Y+Y0-YT; - Z = Z+Z0-ZT; - SetTarget(X,Y,Z); - Display(theView,myTypeOfRepresentation); - (theView->Viewer())->UpdateLights(); - break; - - case V3d_ExtRADIUSLIGHT : - if (Type() == V3d_DIRECTIONAL) - break; -// it is attempted to preserve the target direction position of the -// source ==> the point is projected on the target source direction. - this->Position(Xi,Yi,Zi); - theView->Project(Xi,Yi,Zi,PXP,PYP); - DX = PXP - PXT; - DY = PYP - PYT; - A1 = DY/DX ; B1 = PYT - A1*PXT; - A2 = -DX/DY; B2 = YPp - A2*XPp; - Xproj = (B2 - B1) / (A1 - A2); - Yproj = A1*Xproj + B1; - if ( (DX*(Xproj-PXT) > 0.) && (DY*(Yproj-PYT) > 0.) ) { - OldRprj = Sqrt ( Square (PXP-PXT) + Square (PYP-PYT) ); - NewRprj = Sqrt ( Square (Xproj-PXT) + Square (Yproj-PYT) ); - Rap = NewRprj/OldRprj; - Rayon = Radius(); - Rayon = Rayon * Rap; - SetRadius(Rayon); - Display(theView,myTypeOfRepresentation); - (theView->Viewer())->UpdateLights(); - } - break; - - case V3d_IntRADIUSLIGHT : - if (Type() == V3d_DIRECTIONAL) - break; -// it is attempted to preserve the target direction position of the -// source ==> the point is projected on the target source direction. - Position(Xi,Yi,Zi); - theView->Project(Xi,Yi,Zi,PXP,PYP); - DX = PXP - PXT; - DY = PYP - PYT; - A1 = DY/DX ; B1 = PYT - A1*PXT; - A2 = -DX/DY; B2 = YPp - A2*XPp; - Xproj = (B2 - B1) / (A1 - A2); - Yproj = A1*Xproj + B1; - if ( (DX*(Xproj-PXP) < 0.) && (DY*(Yproj-PYP) < 0.) ) { - OldRprj = Sqrt ( Square (PXP-PXT) + Square (PYP-PYT) ); - NewRprj = Sqrt ( Square (Xproj-PXP) + Square (Yproj-PYP) ); - Rap = NewRprj/OldRprj; - Rayon = Radius(); - Rayon = Rayon * Rap; -// the source should remain at a fixed position, -// only the target is modified. - - gp_XYZ aPos; - Position (aPos.ChangeCoord (1), aPos.ChangeCoord (2), aPos.ChangeCoord (3)); - gp_XYZ aDir = myTarget.XYZ() - aPos; - aDir.Normalize(); - aDir.Coord(X,Y,Z); - X = Xi + Rayon*X; - Y = Yi + Rayon*Y; - Z = Zi + Rayon*Z; -// the source should remain at a fixed position, -// only the target is modified. - myTarget.SetCoord(X,Y,Z); - Display(theView,myTypeOfRepresentation); - (theView->Viewer())->UpdateLights(); - } - break; - - case V3d_RADIUSTEXTLIGHT : - break; - - case V3d_NOTHING : - break; + theViewer->AddLight (this); } } - -// ======================================================================= -// function : Radius -// purpose : -// ======================================================================= -Standard_Real V3d_PositionLight::Radius() const -{ - Standard_Real Xp,Yp,Zp, Xc,Yc,Zc; - - Position (Xp,Yp,Zp); - myTarget.Coord(Xc,Yc,Zc); - - return Sqrt (Square(Xc - Xp) + Square(Yc - Yp) + Square(Zc - Zp)); -} - -// ======================================================================= -// function : Erase -// purpose : -// ======================================================================= -void V3d_PositionLight::Erase() -{ - if (!myGraphicStructure.IsNull()) myGraphicStructure->Erase(); - if (!myGraphicStructure1.IsNull()) myGraphicStructure1->Erase(); -} - diff --git a/src/V3d/V3d_PositionLight.hxx b/src/V3d/V3d_PositionLight.hxx index 53a9c5003f..f1a656c8b0 100644 --- a/src/V3d/V3d_PositionLight.hxx +++ b/src/V3d/V3d_PositionLight.hxx @@ -22,95 +22,26 @@ #include #include -class V3d_View; class V3d_Viewer; -class V3d_PositionLight; -DEFINE_STANDARD_HANDLE(V3d_PositionLight, V3d_Light) //! Base class for Positional, Spot and Directional Light classes. -class V3d_PositionLight : public V3d_Light +class V3d_PositionLight : public Graphic3d_CLight { -public: - - //! Defines the position of the light source. Should be redefined! - Standard_EXPORT virtual void SetPosition (Standard_Real theX, - Standard_Real theY, - Standard_Real theZ) = 0; - - //! Defines the target of the light (the center of the sphere). - Standard_EXPORT void SetTarget (const Standard_Real theX, - const Standard_Real theY, - const Standard_Real theZ); - - //! Define the radius. - Standard_EXPORT void SetRadius (const Standard_Real theRadius); - - //! Calculate the position of the light, on the hide face of the picking sphere. - Standard_EXPORT void OnHideFace (const Handle(V3d_View)& theView); - - //! Calculate the position of the light, on the seen face of the picking sphere. - Standard_EXPORT void OnSeeFace (const Handle(V3d_View)& theView); - - //! Tracking the light position, or the light space, - //! or the radius of the light space, that depends of - //! initial picking "theWhatPick" (see the pick method). - //! If theWhatPick is SPACELIGHT, then the parameters - //! theXpix, theYpix are the coordinates of a translation vector. - Standard_EXPORT void Tracking (const Handle(V3d_View)& theView, - const V3d_TypeOfPickLight theWathPick, - const Standard_Integer theXpix, - const Standard_Integer theYpix); - - //! Display the graphic structure of light source - //! in the chosen view. We have three type of representation - //! - SIMPLE : Only the light source is displayed. - //! - PARTIAL : The light source and the light space are - //! displayed. - //! - COMPLETE : The light source, the light space and the - //! radius of light space are displayed. - //! We can choose the "SAMELAST" as parameter of representation - //! In this case the graphic structure representation will be - //! the last displayed. - Standard_EXPORT virtual void Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theRepresentation = V3d_SIMPLE); - - //! Erase the graphic structure of light source. - Standard_EXPORT void Erase(); - - //! Returns the radius of the picking sphere. - Standard_EXPORT Standard_Real Radius() const; - - //! Returns the visibility status - //! If True the source is visible. - //! If False it's hidden. - Standard_EXPORT Standard_Boolean SeeOrHide (const Handle(V3d_View)& theView) const; - - //! Returns the position of the light source. - Standard_EXPORT virtual void Position (Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const = 0; - - //! Returns the position of the target of the light source. - void Target (Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const { myTarget.Coord (theX, theY, theZ); } - - DEFINE_STANDARD_RTTIEXT(V3d_PositionLight,V3d_Light) - + DEFINE_STANDARD_RTTIEXT(V3d_PositionLight, Graphic3d_CLight) protected: - Standard_EXPORT V3d_PositionLight (const Handle(V3d_Viewer)& theViewer); + //! Protected constructor. + Standard_EXPORT V3d_PositionLight (Graphic3d_TypeOfLightSource theType, + const Handle(V3d_Viewer)& theViewer); +//! @name hidden properties not applicable to positional light protected: - gp_Pnt myTarget; - V3d_TypeOfRepresentation myTypeOfRepresentation; + using Graphic3d_CLight::Position; + using Graphic3d_CLight::SetPosition; -private: - - //! Defines representation of the light source. - Standard_EXPORT virtual void Symbol (const Handle(Graphic3d_Group)& theSymbol, - const Handle(V3d_View)& theView) const = 0; }; +DEFINE_STANDARD_HANDLE(V3d_PositionLight, Graphic3d_CLight) + #endif // _V3d_PositionLight_HeaderFile diff --git a/src/V3d/V3d_PositionalLight.cxx b/src/V3d/V3d_PositionalLight.cxx index a9456cdbc1..9cc8660b15 100644 --- a/src/V3d/V3d_PositionalLight.cxx +++ b/src/V3d/V3d_PositionalLight.cxx @@ -13,19 +13,20 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - IMPLEMENT_STANDARD_RTTIEXT(V3d_PositionalLight,V3d_PositionLight) +// ======================================================================= +// function : V3d_PositionalLight +// purpose : +// ======================================================================= +V3d_PositionalLight::V3d_PositionalLight (const gp_Pnt& thePos, + const Quantity_Color& theColor) +: V3d_PositionLight (Graphic3d_TOLS_POSITIONAL, Handle(V3d_Viewer)()) +{ + SetColor (theColor); + SetPosition (thePos); +} + // ======================================================================= // function : V3d_PositionalLight // purpose : @@ -37,244 +38,9 @@ V3d_PositionalLight::V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer, const Quantity_Color& theColor, const Standard_Real theConstAttenuation, const Standard_Real theLinearAttenuation) -: V3d_PositionLight (theViewer) +: V3d_PositionLight (Graphic3d_TOLS_POSITIONAL, theViewer) { - SetType (V3d_POSITIONAL); SetColor (theColor); - SetTarget (0., 0., 0.); SetPosition (theX, theY, theZ); - SetAttenuation (theConstAttenuation, theLinearAttenuation); -} - -// ======================================================================= -// function : V3d_PositionalLight -// purpose : -// ======================================================================= -V3d_PositionalLight::V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer, - const Standard_Real theXt, - const Standard_Real theYt, - const Standard_Real theZt, - const Standard_Real theXp, - const Standard_Real theYp, - const Standard_Real theZp, - const Quantity_Color& theColor, - const Standard_Real theConstAttenuation, - const Standard_Real theLinearAttenuation) -: V3d_PositionLight (theViewer) -{ - SetType (V3d_POSITIONAL); - SetColor (theColor); - SetTarget (theXt, theYt, theZt); - SetPosition (theXp, theYp, theZp); - SetAttenuation (theConstAttenuation, theLinearAttenuation); -} - -// ======================================================================= -// function : SetSmoothRadius -// purpose : -// ======================================================================= -void V3d_PositionalLight::SetSmoothRadius (const Standard_Real theValue) -{ - V3d_BadValue_Raise_if (theValue < 0.0, - "V3d_PositionalLight::SetSmoothRadius," - "Bad value for smoothing radius"); - - myLight.Smoothness = static_cast (theValue); -} - -// ======================================================================= -// function : SetAttenuation -// purpose : -// ======================================================================= -void V3d_PositionalLight::SetAttenuation (const Standard_Real theConstAttenuation, - const Standard_Real theLinearAttenuation) -{ - V3d_BadValue_Raise_if (theConstAttenuation < 0. - || theConstAttenuation > 1. - || theLinearAttenuation < 0. - || theLinearAttenuation > 1., - "V3d_PositionalLight::SetAttenuation, bad coefficients"); - - myLight.ChangeConstAttenuation() = static_cast (theConstAttenuation); - myLight.ChangeLinearAttenuation() = static_cast (theLinearAttenuation); -} - -// ======================================================================= -// function : Symbol -// purpose : -// ======================================================================= -void V3d_PositionalLight::Symbol (const Handle(Graphic3d_Group)& theSymbol, const Handle(V3d_View)& theView) const -{ - Standard_Real Xi,Yi,Zi,Xf,Yf,Zf,Rayon,PXT,PYT,X,Y,Z,XT,YT,ZT; - Standard_Real A,B,C,Dist,Beta,CosBeta,SinBeta,Coef,X1,Y1,Z1; - Standard_Real VX,VY,VZ; - Standard_Integer IXP,IYP,j; - TColStd_Array2OfReal MatRot(0,2,0,2); - - theView->Proj(VX,VY,VZ); - this->Position(Xi,Yi,Zi); - Rayon = this->Radius(); - theView->Project(Xi,Yi,Zi,PXT,PYT); - theView->Convert(PXT,PYT,IXP,IYP); -// 3D Coordinate in the plane of projection of the source. - theView->Convert(IXP,IYP,XT,YT,ZT); - theView->Convert(PXT,PYT+Rayon,IXP,IYP); - theView->Convert(IXP,IYP,X,Y,Z); - X = X+Xi-XT; Y = Y+Yi-YT; Z = Z+Zi-ZT; - Dist = Sqrt( Square(X-Xi) + Square(Y-Yi) + Square(Z-Zi) ); -// Axis of rotation. - A = (X-Xi)/Dist; - B = (Y-Yi)/Dist; - C = (Z-Zi)/Dist; - -// A sphere is drawn - V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.); - for( j=1 ; j<=3 ; j++ ) { - Beta = j * M_PI / 4.; - CosBeta = Cos(Beta); - SinBeta = Sin(Beta); - Coef = 1. - CosBeta; - MatRot(0,0) = A * A + (1. - A * A) * CosBeta; - MatRot(0,1) = -C * SinBeta + Coef * A * B; - MatRot(0,2) = B * SinBeta + Coef * A * C; - MatRot(1,0) = C * SinBeta + Coef * A * B; - MatRot(1,1) = B * B + (1. - B * B) * CosBeta; - MatRot(1,2) = -A * SinBeta + Coef * B * C; - MatRot(2,0) = -B * SinBeta + Coef * A * C; - MatRot(2,1) = A * SinBeta + Coef * B * C; - MatRot(2,2) = C * C + (1. - C * C) * CosBeta; - Xf = Xi * MatRot(0,0) + Yi * MatRot(0,1) + Zi * MatRot(0,2); - Yf = Xi * MatRot(1,0) + Yi * MatRot(1,1) + Zi * MatRot(1,2); - Zf = Xi * MatRot(2,0) + Yi * MatRot(2,1) + Zi * MatRot(2,2); -// Rotation of the normal - X1 = VX * MatRot(0,0) + VY * MatRot(0,1) + VZ * MatRot(0,2); - Y1 = VX * MatRot(1,0) + VY * MatRot(1,1) + VZ * MatRot(1,2); - Z1 = VX * MatRot(2,0) + VY * MatRot(2,1) + VZ * MatRot(2,2); - VX = X1 + Xi - Xf ; VY = Y1 + Yi - Yf ; VZ = Z1 + Zi - Zf; - V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.); - } -} - -// ======================================================================= -// function : Display -// purpose : -// ======================================================================= -void V3d_PositionalLight::Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theRepresentation) -{ - Standard_Real X,Y,Z,Rayon; - Standard_Real X0,Y0,Z0,VX,VY,VZ; - Standard_Real X1,Y1,Z1; - Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini; - V3d_TypeOfRepresentation Pres; - -// Creation of a structure slight of markable elements (position of the -// light, and the domain of lighting represented by a circle) -// Creation of a structure snopick of non-markable elements (target, meridian and -// parallel). - - Pres = theRepresentation; - Handle(V3d_Viewer) TheViewer = theView->Viewer(); - if (!myGraphicStructure.IsNull()) { - myGraphicStructure->Disconnect(myGraphicStructure1); - myGraphicStructure->Clear(); - myGraphicStructure1->Clear(); - if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation; - } - else { - if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE; - Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure = slight; - Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure1 = snopick; - } - - Handle(Graphic3d_Group) gradius, gExtArrow, gIntArrow; - if (Pres == V3d_COMPLETE) - { - gradius = myGraphicStructure->NewGroup(); - gExtArrow = myGraphicStructure->NewGroup(); - gIntArrow = myGraphicStructure->NewGroup(); - } - Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup(); - Handle(Graphic3d_Group) gsphere; - if (Pres == V3d_COMPLETE - || Pres == V3d_PARTIAL) - { - gsphere = myGraphicStructure->NewGroup(); - } - - Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup(); - - X0 = myTarget.X(); - Y0 = myTarget.Y(); - Z0 = myTarget.Z(); - -// Display of the position of the light. - - const Quantity_Color Col1 = this->Color(); - Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d(); - Asp1->SetColor(Col1); - glight->SetPrimitivesAspect(Asp1); - this->Symbol(glight,theView); - -// Display of the markable sphere (limit at the cercle). - - if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) { - - Rayon = this->Radius(); - theView->Proj(VX,VY,VZ); - V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon); - -// Display of the radius of the sphere (line + text) - - if (Pres == V3d_COMPLETE) { - this->Position(X,Y,Z); - Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2); - aPrims->AddVertex(X0,Y0,Z0); - aPrims->AddVertex(X,Y,Z); - gnopick->AddPrimitiveArray(aPrims); - V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.); - V3d::ArrowOfRadius(gIntArrow, X0, Y0, Z0, X0-X, Y0-Y, Z0-Z, M_PI / 15., Rayon / 20.); - TCollection_AsciiString ValOfRadius(Rayon); - Graphic3d_Vertex PText (0.5*(X0+X), 0.5*(Y0+Y), 0.5*(Z0+Z)); - gradius->Text(ValOfRadius.ToCString(),PText,0.01); - } - -// Display of the meridian - - Quantity_Color Col2(Quantity_NOC_GREEN); - Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.); - gnopick->SetPrimitivesAspect(Asp2); - -// Definition of the axis of circle - theView->Up(DXRef,DYRef,DZRef); - this->Position(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - -// Display of the parallel - -// Definition of the axis of circle - theView->Proj(VX,VY,VZ); - theView->Up(X1,Y1,Z1); - DXRef = VY * Z1 - VZ * Y1; - DYRef = VZ * X1 - VX * Z1; - DZRef = VX * Y1 - VY * X1; - this->Position(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - } - - myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT); - myTypeOfRepresentation = Pres; - myGraphicStructure->Display(); + SetAttenuation ((float )theConstAttenuation, (float )theLinearAttenuation); } diff --git a/src/V3d/V3d_PositionalLight.hxx b/src/V3d/V3d_PositionalLight.hxx index 0993d9d308..33905e5edf 100644 --- a/src/V3d/V3d_PositionalLight.hxx +++ b/src/V3d/V3d_PositionalLight.hxx @@ -19,25 +19,28 @@ #include -class V3d_PositionalLight; -DEFINE_STANDARD_HANDLE(V3d_PositionalLight, V3d_PositionLight) - -//! Creation and modification of an isolated -//! (positional) light source. +//! Creation and modification of an isolated (positional) light source. +//! It is also defined by the color and two attenuation factors ConstAttentuation() and LinearAttentuation(). +//! The resulting attenuation factor determining the illumination of a surface depends on the following formula: +//! @code +//! F = 1 / (ConstAttenuation() + LinearAttenuation() * Distance) +//! @endcode +//! Where Distance is the distance of the isolated source from the surface. class V3d_PositionalLight : public V3d_PositionLight { + DEFINE_STANDARD_RTTIEXT(V3d_PositionalLight, V3d_PositionLight) public: - //! Creates an isolated light source theX, theY, theZ in the viewer. - //! It is also defined by the color theColor and - //! two attenuation factors theConstAttentuation, theLinearAttentuation. - //! The resulting attenuation factor determining the - //! illumination of a surface depends on the following - //! formula : - //! F = 1/(ConstAttenuation + LinearAttenuation*Length) - //! Length is the distance of the isolated source - //! from the surface. //! Warning! raises BadValue from V3d - //! if one of the attenuation coefficients is not in range [0, 1]. + //! Creates an isolated light source in the viewer with default attenuation factors (1.0, 0.0). + Standard_EXPORT V3d_PositionalLight (const gp_Pnt& thePos, + const Quantity_Color& theColor = Quantity_NOC_WHITE); + + using Graphic3d_CLight::Position; + using Graphic3d_CLight::SetPosition; + +public: + + Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()") Standard_EXPORT V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theX, const Standard_Real theY, @@ -46,85 +49,18 @@ public: const Standard_Real theConstAttenuation = 1.0, const Standard_Real theLinearAttenuation = 0.0); - //! Creates a light source of the Positional type in the viewer. - //! theXt, theYt, theZt : Coordinate of Target light source. - //! theXp, theYp, theZp : Coordinate of Position light source. - //! The light source is also defined by the color Color - //! and two attenuation factors theConstAttentuation, - //! theLinearAttentuation that determine the illumination of a - //! surface using the following formula : - //! F = 1/(ConstAttenuation + LinearAttenuation*Length) - //! Length is the distance of the isolated source - //! from the surface. //! Warning! raises BadValue from V3d - //! if one of the attenuation coefficients is not between 0 et 1. - Standard_EXPORT V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer, - const Standard_Real theXt, - const Standard_Real theYt, - const Standard_Real theZt, - const Standard_Real theXp, - const Standard_Real theYp, - const Standard_Real theZp, - const Quantity_Color& theColor = Quantity_NOC_WHITE, - const Standard_Real theConstAttenuation = 1.0, - const Standard_Real theLinearAttenuation = 0.0); - - //! Defines the position of the light source. - virtual void SetPosition (Standard_Real theX, - Standard_Real theY, - Standard_Real theZ) Standard_OVERRIDE - { - myLight.Position.x() = theX; - myLight.Position.y() = theY; - myLight.Position.z() = theZ; - } - - //! Defines the attenuation factors. - //! Warning: raises BadValue from V3d - //! if one of the attenuation coefficients is not between 0 et 1. - Standard_EXPORT void SetAttenuation (const Standard_Real theConstAttenuation, - const Standard_Real theLinearAttenuation); - - //! Modifies the smoothing radius - Standard_EXPORT void SetSmoothRadius (const Standard_Real theValue); - - //! Display the graphic structure of light source - //! in the chosen view. We have three type of representation - //! - SIMPLE : Only the light source is displayed. - //! - PARTIAL : The light source and the light space are - //! displayed. - //! - COMPLETE : The light source, the light space and the - //! radius of light space are displayed. - //! We can choose the "SAMELAST" as parameter of representation - //! In this case the graphic structure representation will be - //! the last displayed. - Standard_EXPORT void Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theRepresentation) Standard_OVERRIDE; - - //! Returns the position of the light source. - void Position (Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const Standard_OVERRIDE - { - theX = myLight.Position.x(); - theY = myLight.Position.y(); - theZ = myLight.Position.z(); - } - - //! Returns the attenuation factors. - void Attenuation (Standard_Real& theConstAttenuation, - Standard_Real& theLinearAttenuation) const - { - theConstAttenuation = myLight.ConstAttenuation(); - theLinearAttenuation = myLight.LinearAttenuation(); - } - - DEFINE_STANDARD_RTTIEXT(V3d_PositionalLight,V3d_PositionLight) - +//! @name hidden properties not applicable to positional light private: - //! Defined the representation of the positional light source. - Standard_EXPORT void Symbol (const Handle(Graphic3d_Group)& theSymbol, - const Handle(V3d_View)& theView) const Standard_OVERRIDE; + using Graphic3d_CLight::Direction; + using Graphic3d_CLight::SetDirection; + using Graphic3d_CLight::Angle; + using Graphic3d_CLight::SetAngle; + using Graphic3d_CLight::Concentration; + using Graphic3d_CLight::SetConcentration; + }; +DEFINE_STANDARD_HANDLE(V3d_PositionalLight, V3d_PositionLight) + #endif // _V3d_PositionalLight_HeaderFile diff --git a/src/V3d/V3d_SpotLight.cxx b/src/V3d/V3d_SpotLight.cxx index 53a8fa58d6..1329ec3cf1 100644 --- a/src/V3d/V3d_SpotLight.cxx +++ b/src/V3d/V3d_SpotLight.cxx @@ -13,18 +13,38 @@ #include -#include -#include -#include -#include -#include #include -#include -#include -#include IMPLEMENT_STANDARD_RTTIEXT(V3d_SpotLight,V3d_PositionLight) +// ======================================================================= +// function : V3d_SpotLight +// purpose : +// ======================================================================= +V3d_SpotLight::V3d_SpotLight (const gp_Pnt& thePos, + const V3d_TypeOfOrientation theDirection, + const Quantity_Color& theColor) +: V3d_PositionLight (Graphic3d_TOLS_SPOT, Handle(V3d_Viewer)()) +{ + SetColor (theColor); + SetPosition (thePos); + SetDirection (V3d::GetProjAxis (theDirection)); +} + +// ======================================================================= +// function : V3d_SpotLight +// purpose : +// ======================================================================= +V3d_SpotLight::V3d_SpotLight (const gp_Pnt& thePos, + const gp_Dir& theDirection, + const Quantity_Color& theColor) +: V3d_PositionLight (Graphic3d_TOLS_SPOT, Handle(V3d_Viewer)()) +{ + SetColor (theColor); + SetPosition (thePos); + SetDirection (theDirection); +} + // ======================================================================= // function : V3d_SpotLight // purpose : @@ -39,17 +59,14 @@ V3d_SpotLight::V3d_SpotLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theLinearAttenuation, const Standard_Real theConcentration, const Standard_Real theAngle) -: V3d_PositionLight (theViewer) +: V3d_PositionLight (Graphic3d_TOLS_SPOT, theViewer) { - gp_Dir aDir = V3d::GetProjAxis (theDirection); - SetType (V3d_SPOT); SetColor (theColor); - SetTarget (theX + aDir.X(), theY + aDir.Y(), theZ + aDir.Z()); SetPosition (theX, theY, theZ); - SetDirection (aDir.X(), aDir.Y(), aDir.Z()); - SetAttenuation (theConstAttenuation, theLinearAttenuation); - SetConcentration (theConcentration); - SetAngle (theAngle); + SetDirection (V3d::GetProjAxis (theDirection)); + SetAttenuation ((float )theConstAttenuation, (float )theLinearAttenuation); + SetConcentration ((float )theConcentration); + SetAngle ((float )theAngle); } // ======================================================================= @@ -68,16 +85,14 @@ V3d_SpotLight::V3d_SpotLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theLinearAttenuation, const Standard_Real theConcentration, const Standard_Real theAngle) -: V3d_PositionLight (theViewer) +: V3d_PositionLight (Graphic3d_TOLS_SPOT, theViewer) { - SetType (V3d_SPOT); SetColor (theColor); - SetTarget (theXt, theYt, theZt); SetPosition (theXp, theYp, theZp); SetDirection (theXt - theXp, theYt - theYp, theZt - theZp); - SetAttenuation (theConstAttenuation, theLinearAttenuation); - SetConcentration (theConcentration); - SetAngle (theAngle); + SetAttenuation ((float )theConstAttenuation, (float )theLinearAttenuation); + SetConcentration ((float )theConcentration); + SetAngle ((float )theAngle); } // ======================================================================= @@ -86,190 +101,5 @@ V3d_SpotLight::V3d_SpotLight (const Handle(V3d_Viewer)& theViewer, // ======================================================================= void V3d_SpotLight::SetDirection (V3d_TypeOfOrientation theDirection) { - gp_Dir aDir = V3d::GetProjAxis (theDirection); - SetDirection (aDir.X(), aDir.Y(), aDir.Z()); -} - -// ======================================================================= -// function : SetAttenuation -// purpose : -// ======================================================================= -void V3d_SpotLight::SetAttenuation (const Standard_Real theConstAttenuation, - const Standard_Real theLinearAttenuation) -{ - V3d_BadValue_Raise_if (theConstAttenuation < 0. || - theConstAttenuation > 1. || - theLinearAttenuation < 0. || - theLinearAttenuation > 1 , - "V3d_SpotLight::SetAttenuation, " - "bad coefficients"); - - myLight.ChangeConstAttenuation() = static_cast (theConstAttenuation); - myLight.ChangeLinearAttenuation() = static_cast (theLinearAttenuation); -} - -// ======================================================================= -// function : SetConcentration -// purpose : -// ======================================================================= -void V3d_SpotLight::SetConcentration (const Standard_Real theConcentration) -{ - V3d_BadValue_Raise_if (theConcentration < 0. || - theConcentration > 1., - "V3d_SpotLight::SetConcentration, " - "bad coefficient"); - - myLight.ChangeConcentration() = static_cast (theConcentration); -} - -// ======================================================================= -// function : SetAngle -// purpose : -// ======================================================================= -void V3d_SpotLight::SetAngle (const Standard_Real theAngle) -{ - V3d_BadValue_Raise_if (theAngle <= 0. || - theAngle >= M_PI, - "V3d_SpotLight::SetAngle, " - "bad angle"); - - myLight.ChangeAngle() = static_cast (theAngle); -} -// ======================================================================= -// function : Symbol -// purpose : -// ======================================================================= -void V3d_SpotLight::Symbol (const Handle(Graphic3d_Group)& theSymbol, - const Handle(V3d_View)& ) const -{ - Standard_Real X,Y,Z; - Standard_Real DX,DY,DZ; - this->Position(X,Y,Z); - this->Direction(DX,DY,DZ); - - V3d::ArrowOfRadius(theSymbol,X,Y,Z,-DX,-DY,-DZ,M_PI/8.,this->Radius()/15.); -} - -// ======================================================================= -// function : Display -// purpose : -// ======================================================================= -void V3d_SpotLight::Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theTPres) -{ - Standard_Real X,Y,Z,Rayon; - Standard_Real X0,Y0,Z0,VX,VY,VZ; - Standard_Real X1,Y1,Z1; - Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini; - V3d_TypeOfRepresentation Pres; - -// Creation of a structure slight of markable elements (position of the -// light, and the domain of lighting represented by a circle) -// Creation of a structure snopick of non-markable elements (target, meridian and -// parallel).// - - Pres = theTPres; - Handle(V3d_Viewer) TheViewer = theView->Viewer(); - if (!myGraphicStructure.IsNull()) { - myGraphicStructure->Disconnect(myGraphicStructure1); - myGraphicStructure->Clear(); - myGraphicStructure1->Clear(); - if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation; - } - else { - if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE; - Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure = slight; - Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); - myGraphicStructure1 = snopick; - } - - Handle(Graphic3d_Group) gradius, gExtArrow, gIntArrow; - if (Pres == V3d_COMPLETE) - { - gradius = myGraphicStructure->NewGroup(); - gExtArrow = myGraphicStructure->NewGroup(); - gIntArrow = myGraphicStructure->NewGroup(); - } - Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup(); - Handle(Graphic3d_Group) gsphere; - if (Pres == V3d_COMPLETE - || Pres == V3d_PARTIAL) - { - gsphere = myGraphicStructure->NewGroup(); - } - - Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup(); - - X0 = myTarget.X(); - Y0 = myTarget.Y(); - Z0 = myTarget.Z(); - -//Display of the position of the light. - - const Quantity_Color Col1 = this->Color(); - Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d(); - Asp1->SetColor(Col1); - glight->SetPrimitivesAspect(Asp1); - this->Symbol(glight,theView); - -// Display of the reference sphere (limited by circle). - - if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) { - - Rayon = this->Radius(); - theView->Proj(VX,VY,VZ); - V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon); - -// Display of the radius of the sphere (line + text) - - if (Pres == V3d_COMPLETE) { - this->Position(X,Y,Z); - Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2); - aPrims->AddVertex(X0,Y0,Z0); - aPrims->AddVertex(X,Y,Z); - gnopick->AddPrimitiveArray(aPrims); - V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.); - V3d::ArrowOfRadius(gIntArrow,X0,Y0,Z0,X0-X,Y0-Y,Z0-Z,M_PI/15.,Rayon/20.); - TCollection_AsciiString ValOfRadius(Rayon); - Graphic3d_Vertex PText ( .5*(X0+X), .5*(Y0+Y), .5*(Z0+Z) ); - gradius->Text(ValOfRadius.ToCString(),PText,0.01); - } - -// Display of the meridian - - Quantity_Color Col2(Quantity_NOC_GREEN); - Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.); - gnopick->SetPrimitivesAspect(Asp2); - -// Definition of the axis of the circle - theView->Up(DXRef,DYRef,DZRef); - this->Position(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - -// Display of the parallel - -// Definition of the axis of the circle - theView->Proj(VX,VY,VZ); - theView->Up(X1,Y1,Z1); - DXRef = VY * Z1 - VZ * Y1; - DYRef = VZ * X1 - VX * Z1; - DZRef = VX * Y1 - VY * X1; - this->Position(X,Y,Z); - DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0; - VX = DYRef*DZini - DZRef*DYini; - VY = DZRef*DXini - DXRef*DZini; - VZ = DXRef*DYini - DYRef*DXini; - - V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon); - } - - myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT); - myTypeOfRepresentation = Pres; - myGraphicStructure->Display(); + SetDirection (V3d::GetProjAxis (theDirection)); } diff --git a/src/V3d/V3d_SpotLight.hxx b/src/V3d/V3d_SpotLight.hxx index 65fe287022..8d1de06551 100644 --- a/src/V3d/V3d_SpotLight.hxx +++ b/src/V3d/V3d_SpotLight.hxx @@ -20,28 +20,41 @@ #include #include -class V3d_Viewer; -class V3d_SpotLight; -DEFINE_STANDARD_HANDLE(V3d_SpotLight, V3d_PositionLight) - //! Creation and modification of a spot. +//! The attenuation factor F determines the illumination of a surface: +//! @code +//! F = 1/(ConstAttenuation() + LinearAttenuation() * Distance) +//! @endcode +//! Where Distance is the distance from the source to the surface. +//! The default values (1.0, 0.0) correspond to a minimum of attenuation. +//! The concentration factor determines the dispersion of the light on the surface, the default value (1.0) corresponds to a minimum of dispersion. class V3d_SpotLight : public V3d_PositionLight { + DEFINE_STANDARD_RTTIEXT(V3d_SpotLight, V3d_PositionLight) public: - //! Creates a light source of the Spot type in the viewer. - //! The attenuation factor F which determines - //! the illumination of a surface depends on the following formula : - //! F = 1/(theConstAttenuation + theLinearAttenuation*Length) - //! Length is the distance from the source to the surface. - //! The default values (1.0,0.0) correspond to a minimum - //! of attenuation. - //! The concentration factor determines the dispersion - //! of the light on the surface, the default value - //! (1.0) corresponds to a minimum of dispersion. - //! Warning! raises BadValue from V3d - - //! If one of the coefficients is not between 0 and 1. - //! If the lighting angle is <= 0 or > PI. + //! Creates a light source of the Spot type in the viewer with default attenuation factors (1.0, 0.0), + //! concentration factor 1.0 and spot angle 30 degrees. + Standard_EXPORT V3d_SpotLight (const gp_Pnt& thePos, + const V3d_TypeOfOrientation theDirection = V3d_XnegYnegZpos, + const Quantity_Color& theColor = Quantity_NOC_WHITE); + + //! Creates a light source of the Spot type in the viewer with default attenuation factors (1.0, 0.0), + //! concentration factor 1.0 and spot angle 30 degrees. + Standard_EXPORT V3d_SpotLight (const gp_Pnt& thePos, + const gp_Dir& theDirection, + const Quantity_Color& theColor = Quantity_NOC_WHITE); + + //! Defines the direction of the light source + //! according to a predefined directional vector. + Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theOrientation); + using Graphic3d_CLight::SetDirection; + using Graphic3d_CLight::Position; + using Graphic3d_CLight::SetPosition; + +public: + + Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()") Standard_EXPORT V3d_SpotLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theX, const Standard_Real theY, @@ -53,13 +66,9 @@ public: const Standard_Real theConcentration = 1.0, const Standard_Real theAngle = 0.523599); - //! Creates a light source of the Spot type in the viewer. //! theXt, theYt, theZt : Coordinate of light source Target. //! theXp, theYp, theZp : Coordinate of light source Position. - //! The others parameters describe before. - //! Warning! raises BadValue from V3d - - //! If one of the coefficients is not between 0 and 1. - //! If the lighting angle is <= 0 or > PI. + Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()") Standard_EXPORT V3d_SpotLight (const Handle(V3d_Viewer)& theViewer, const Standard_Real theXt, const Standard_Real theYt, @@ -73,99 +82,8 @@ public: const Standard_Real theConcentration = 1.0, const Standard_Real theAngle = 0.523599); - //! Defines the position of the light source. - virtual void SetPosition (Standard_Real theX, - Standard_Real theY, - Standard_Real theZ) Standard_OVERRIDE - { - myLight.Position.x() = theX; - myLight.Position.y() = theY; - myLight.Position.z() = theZ; - } - - //! Defines the direction of the light source. - //! If the normal vector is NULL. - void SetDirection (Standard_Real theVx, - Standard_Real theVy, - Standard_Real theVz) - { - myLight.Direction.x() = static_cast (theVx); - myLight.Direction.y() = static_cast (theVy); - myLight.Direction.z() = static_cast (theVz); - } - - //! Defines the direction of the light source - //! according to a predefined directional vector. - Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theOrientation); - - //! Defines the coefficients of attenuation. - //! Warning! raises BadValue from V3d - //! if one of the coefficient is < 0 or > 1. - Standard_EXPORT void SetAttenuation (const Standard_Real theConstAttenuation, - const Standard_Real theLinearAttenuation); - - //! Defines the coefficient of concentration. - //! if the coefficient is < 0 or > 1. - Standard_EXPORT void SetConcentration (const Standard_Real theConcentration); - - //! Defines the spot angle in RADIANS. - //! Warning: raises BadValue from from V3d - //! If the angle is <= 0 or > PI. - Standard_EXPORT void SetAngle (const Standard_Real theAngle); - - //! Display the graphic structure of light source - //! in the chosen view. We have three type of representation - //! - SIMPLE : Only the light source is displayed. - //! - PARTIAL : The light source and the light space are - //! displayed. - //! - COMPLETE : The light source, the light space and the - //! radius of light space are displayed. - //! We can choose the "SAMELAST" as parameter of representation - //! In this case the graphic structure representation will be - //! the last displayed. - Standard_EXPORT void Display (const Handle(V3d_View)& theView, - const V3d_TypeOfRepresentation theRepresentation) Standard_OVERRIDE; - - //! Returns the direction of the light source defined by theVx, theVy, theVz. - void Direction (Standard_Real& theVx, - Standard_Real& theVy, - Standard_Real& theVz) const - { - theVx = myLight.Direction.x(); - theVy = myLight.Direction.y(); - theVz = myLight.Direction.z(); - } - - //! Returns the position of the light source. - virtual void Position (Standard_Real& theX, - Standard_Real& theY, - Standard_Real& theZ) const Standard_OVERRIDE - { - theX = myLight.Position.x(); - theY = myLight.Position.y(); - theZ = myLight.Position.z(); - } - - //! Returns the attenuation factors A1,A2 of the light source. - void Attenuation (Standard_Real& theConstAttentuation, - Standard_Real& theLinearAttentuation) const - { - theConstAttentuation = myLight.ConstAttenuation(); - theLinearAttentuation = myLight.LinearAttenuation(); - } - - Standard_Real Concentration() const { return myLight.Concentration(); } - - //! Returns the spot angle. - Standard_Real Angle() const { return myLight.Angle(); } - - DEFINE_STANDARD_RTTIEXT(V3d_SpotLight,V3d_PositionLight) - -private: - - //! Defines the representation of the spot light source. - Standard_EXPORT void Symbol (const Handle(Graphic3d_Group)& theSymbol, - const Handle(V3d_View)& theView) const Standard_OVERRIDE; }; +DEFINE_STANDARD_HANDLE(V3d_SpotLight, V3d_PositionLight) + #endif // _V3d_SpotLight_HeaderFile diff --git a/src/V3d/V3d_TypeOfLight.hxx b/src/V3d/V3d_TypeOfLight.hxx index cefb25dce1..4ae6acbcf6 100644 --- a/src/V3d/V3d_TypeOfLight.hxx +++ b/src/V3d/V3d_TypeOfLight.hxx @@ -17,13 +17,8 @@ #ifndef _V3d_TypeOfLight_HeaderFile #define _V3d_TypeOfLight_HeaderFile -//! Determines the type of light. -enum V3d_TypeOfLight -{ -V3d_AMBIENT, -V3d_DIRECTIONAL, -V3d_POSITIONAL, -V3d_SPOT -}; +#include + +typedef Graphic3d_TypeOfLightSource V3d_TypeOfLight; #endif // _V3d_TypeOfLight_HeaderFile diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index ae5bed8eb5..250739e15b 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -377,10 +377,10 @@ Standard_Boolean V3d_View::IsEmpty() const //============================================================================= void V3d_View::UpdateLights() const { - Graphic3d_ListOfCLight aLights; + Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet(); for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next()) { - aLights.Append (anActiveLightIter.Value()->Light()); + aLights->Add (anActiveLightIter.Value()); } myView->SetLights (aLights); } diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx index 02b76de909..60afb3e273 100644 --- a/src/V3d/V3d_View.hxx +++ b/src/V3d/V3d_View.hxx @@ -77,7 +77,6 @@ class Graphic3d_TextureEnv; class Standard_MultiplyDefined; class Standard_TypeMismatch; class V3d_BadValue; -class V3d_Light; class V3d_UnMapped; class V3d_View; diff --git a/src/V3d/V3d_Viewer.cxx b/src/V3d/V3d_Viewer.cxx index d2c5798a01..8c5db1e2ed 100644 --- a/src/V3d/V3d_Viewer.cxx +++ b/src/V3d/V3d_Viewer.cxx @@ -457,6 +457,10 @@ void V3d_Viewer::SetDefaultLights() DelLight (aLight); } - SetLightOn (new V3d_DirectionalLight (this, V3d_Zneg, Quantity_NOC_WHITE, Standard_True)); - SetLightOn (new V3d_AmbientLight (this)); + Handle(V3d_DirectionalLight) aDirLight = new V3d_DirectionalLight (V3d_Zneg, Quantity_NOC_WHITE, Standard_True); + Handle(V3d_AmbientLight) anAmbLight = new V3d_AmbientLight (Quantity_NOC_WHITE); + AddLight (aDirLight); + AddLight (anAmbLight); + SetLightOn (aDirLight); + SetLightOn (anAmbLight); } diff --git a/src/V3d/V3d_Viewer.hxx b/src/V3d/V3d_Viewer.hxx index ab3d5295ca..11a56c2d2d 100644 --- a/src/V3d/V3d_Viewer.hxx +++ b/src/V3d/V3d_Viewer.hxx @@ -59,7 +59,6 @@ class Graphic3d_Group; class Graphic3d_Structure; class V3d_BadValue; class V3d_CircularGrid; -class V3d_Light; class V3d_RectangularGrid; class V3d_View; class Quantity_Color; @@ -71,7 +70,6 @@ class Quantity_Color; class V3d_Viewer : public Standard_Transient { friend class V3d_View; - friend class V3d_Light; DEFINE_STANDARD_RTTIEXT(V3d_Viewer, Standard_Transient) public: @@ -258,7 +256,10 @@ public: //! @name lights management //! Deactivate all the Lights defined in this viewer. Standard_EXPORT void SetLightOff(); - + + //! Adds Light in Sequence Of Lights. + Standard_EXPORT void AddLight (const Handle(V3d_Light)& theLight); + //! Delete Light in Sequence Of Lights. Standard_EXPORT void DelLight (const Handle(V3d_Light)& theLight); @@ -457,9 +458,6 @@ private: //! Delete View in Sequence Of Views. Standard_EXPORT void DelView (const Handle(V3d_View)& theView); - //! Adds Light in Sequence Of Lights. - Standard_EXPORT void AddLight (const Handle(V3d_Light)& theLight); - private: Handle(Graphic3d_GraphicDriver) myDriver; diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index a8f65a72a5..6069f55da4 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -9213,6 +9213,7 @@ static int VDefaults (Draw_Interpretor& theDi, //! Auxiliary method inline void addLight (const Handle(V3d_Light)& theLightNew, + const Graphic3d_ZLayerId theLayer, const Standard_Boolean theIsGlobal) { if (theLightNew.IsNull()) @@ -9220,13 +9221,28 @@ inline void addLight (const Handle(V3d_Light)& theLightNew, return; } - if (theIsGlobal) + Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext(); + if (theLayer == Graphic3d_ZLayerId_UNKNOWN) { - ViewerTest::GetViewerFromContext()->SetLightOn (theLightNew); + aViewer->AddLight (theLightNew); + if (theIsGlobal) + { + aViewer->SetLightOn (theLightNew); + } + else + { + ViewerTest::CurrentView()->SetLightOn (theLightNew); + } } else { - ViewerTest::CurrentView()->SetLightOn (theLightNew); + Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer); + if (aSettings.Lights().IsNull()) + { + aSettings.SetLights (new Graphic3d_LightSet()); + } + aSettings.Lights()->Add (theLightNew); + aViewer->SetZLayerSettings (theLayer, aSettings); } } @@ -9273,7 +9289,9 @@ static int VLight (Draw_Interpretor& theDi, { Handle(V3d_Light) aLight = aLightIter.Value(); const Quantity_Color aColor = aLight->Color(); - theDi << "Light" << aLightId << "\n"; + theDi << "Light #" << aLightId + << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "") + << " [" << aLight->GetId() << "]" << "\n"; switch (aLight->Type()) { case V3d_AMBIENT: @@ -9284,53 +9302,39 @@ static int VLight (Draw_Interpretor& theDi, } case V3d_DIRECTIONAL: { - Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight); theDi << " Type: Directional\n"; theDi << " Intensity: " << aLight->Intensity() << "\n"; theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"; theDi << " Smoothness: " << aLight->Smoothness() << "\n"; - if (!aLightDir.IsNull()) - { - aLightDir->Position (anXYZ[0], anXYZ[1], anXYZ[2]); - theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; - aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]); - theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; - } + aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; break; } case V3d_POSITIONAL: { - Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight); theDi << " Type: Positional\n"; theDi << " Intensity: " << aLight->Intensity() << "\n"; theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"; theDi << " Smoothness: " << aLight->Smoothness() << "\n"; - if (!aLightPos.IsNull()) - { - aLightPos->Position (anXYZ[0], anXYZ[1], anXYZ[2]); - theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; - aLightPos->Attenuation (anAtten[0], anAtten[1]); - theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n"; - } + aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLight->Attenuation (anAtten[0], anAtten[1]); + theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n"; break; } case V3d_SPOT: { - Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight); theDi << " Type: Spot\n"; theDi << " Intensity: " << aLight->Intensity() << "\n"; theDi << " Headlight: " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n"; - if (!aLightSpot.IsNull()) - { - aLightSpot->Position (anXYZ[0], anXYZ[1], anXYZ[2]); - theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; - aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]); - theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; - aLightSpot->Attenuation (anAtten[0], anAtten[1]); - theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n"; - theDi << " Angle: " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n"; - theDi << " Exponent: " << aLightSpot->Concentration() << "\n"; - } + aLight->Position (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Position: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]); + theDi << " Direction: " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n"; + aLight->Attenuation (anAtten[0], anAtten[1]); + theDi << " Atten.: " << anAtten[0] << " " << anAtten[1] << "\n"; + theDi << " Angle: " << (aLight->Angle() * 180.0 / M_PI) << "\n"; + theDi << " Exponent: " << aLight->Concentration() << "\n"; break; } default: @@ -9339,22 +9343,19 @@ static int VLight (Draw_Interpretor& theDi, break; } } - theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << "\n"; + theDi << " Color: " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n"; } } Handle(V3d_Light) aLightNew; Handle(V3d_Light) aLightOld; + Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN; Standard_Boolean isGlobal = Standard_True; Standard_Boolean toCreate = Standard_False; ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView); for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt) { - Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew; - Handle(V3d_AmbientLight) aLightAmb = Handle(V3d_AmbientLight) ::DownCast (aLightCurr); - Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLightCurr); - Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight) ::DownCast (aLightCurr); - Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight) ::DownCast (aLightCurr); + Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew; TCollection_AsciiString aName, aValue; const TCollection_AsciiString anArg (theArgVec[anArgIt]); @@ -9367,96 +9368,177 @@ static int VLight (Draw_Interpretor& theDi, if (anArgCase.IsEqual ("NEW") || anArgCase.IsEqual ("ADD") - || anArgCase.IsEqual ("CREATE")) + || anArgCase.IsEqual ("CREATE") + || anArgCase.IsEqual ("-NEW") + || anArgCase.IsEqual ("-ADD") + || anArgCase.IsEqual ("-CREATE")) { toCreate = Standard_True; } - else if (anArgCase.IsEqual ("GLOB") - || anArgCase.IsEqual ("GLOBAL")) + else if (anArgCase.IsEqual ("-LAYER") + || anArgCase.IsEqual ("-ZLAYER")) { - isGlobal = Standard_True; - } - else if (anArgCase.IsEqual ("LOC") - || anArgCase.IsEqual ("LOCAL")) - { - isGlobal = Standard_False; - } - else if (anArgCase.IsEqual ("DEF") - || anArgCase.IsEqual ("DEFAULTS")) - { - toCreate = Standard_False; - aViewer->SetDefaultLights(); - } - else if (anArgCase.IsEqual ("CLR") - || anArgCase.IsEqual ("CLEAR")) - { - toCreate = Standard_False; - for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();) - { - Handle(V3d_Light) aLight = aLightIter.Value(); - aViewer->DelLight (aLight); - aLightIter = aView->ActiveLightIterator(); - } - } - else if (anArgCase.IsEqual ("AMB") - || anArgCase.IsEqual ("AMBIENT") - || anArgCase.IsEqual ("AMBLIGHT")) - { - addLight (aLightNew, isGlobal); - if (!toCreate) - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } - toCreate = Standard_False; - aLightNew = new V3d_AmbientLight (aViewer); - } - else if (anArgCase.IsEqual ("DIRECTIONAL") - || anArgCase.IsEqual ("DIRLIGHT")) - { - addLight (aLightNew, isGlobal); - if (!toCreate) - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } - toCreate = Standard_False; - aLightNew = new V3d_DirectionalLight (aViewer); - } - else if (anArgCase.IsEqual ("SPOT") - || anArgCase.IsEqual ("SPOTLIGHT")) - { - addLight (aLightNew, isGlobal); - if (!toCreate) - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } - toCreate = Standard_False; - aLightNew = new V3d_SpotLight (aViewer, 0.0, 0.0, 0.0); - } - else if (anArgCase.IsEqual ("POSLIGHT") - || anArgCase.IsEqual ("POSITIONAL")) - { - addLight (aLightNew, isGlobal); - if (!toCreate) - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } - toCreate = Standard_False; - aLightNew = new V3d_PositionalLight (aViewer, 0.0, 0.0, 0.0); - } - else if (anArgCase.IsEqual ("CHANGE")) - { - addLight (aLightNew, isGlobal); - aLightNew.Nullify(); if (++anArgIt >= theArgsNb) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } + TCollection_AsciiString aValStr (theArgVec[anArgIt]); + aValStr.LowerCase(); + if (aValStr == "default" + || aValStr == "def") + { + aLayer = Graphic3d_ZLayerId_Default; + } + else if (aValStr == "top") + { + aLayer = Graphic3d_ZLayerId_Top; + } + else if (aValStr == "topmost") + { + aLayer = Graphic3d_ZLayerId_Topmost; + } + else if (aValStr == "toposd" + || aValStr == "osd") + { + aLayer = Graphic3d_ZLayerId_TopOSD; + } + else if (aValStr == "botosd" + || aValStr == "bottom") + { + aLayer = Graphic3d_ZLayerId_BotOSD; + } + else if (aValStr.IsIntegerValue()) + { + aLayer = Draw::Atoi (theArgVec[anArgIt]); + } + else + { + std::cout << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + } + else if (anArgCase.IsEqual ("GLOB") + || anArgCase.IsEqual ("GLOBAL") + || anArgCase.IsEqual ("-GLOB") + || anArgCase.IsEqual ("-GLOBAL")) + { + isGlobal = Standard_True; + } + else if (anArgCase.IsEqual ("LOC") + || anArgCase.IsEqual ("LOCAL") + || anArgCase.IsEqual ("-LOC") + || anArgCase.IsEqual ("-LOCAL")) + { + isGlobal = Standard_False; + } + else if (anArgCase.IsEqual ("DEF") + || anArgCase.IsEqual ("DEFAULTS") + || anArgCase.IsEqual ("-DEF") + || anArgCase.IsEqual ("-DEFAULTS")) + { + toCreate = Standard_False; + aViewer->SetDefaultLights(); + } + else if (anArgCase.IsEqual ("CLR") + || anArgCase.IsEqual ("CLEAR") + || anArgCase.IsEqual ("-CLR") + || anArgCase.IsEqual ("-CLEAR")) + { + toCreate = Standard_False; + + TColStd_SequenceOfInteger aLayers; + aViewer->GetAllZLayers (aLayers); + for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next()) + { + if (aLayeriter.Value() == aLayer + || aLayer == Graphic3d_ZLayerId_UNKNOWN) + { + Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value()); + aSettings.SetLights (Handle(Graphic3d_LightSet)()); + aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings); + if (aLayer != Graphic3d_ZLayerId_UNKNOWN) + { + break; + } + } + } + + if (aLayer == Graphic3d_ZLayerId_UNKNOWN) + { + for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();) + { + Handle(V3d_Light) aLight = aLightIter.Value(); + aViewer->DelLight (aLight); + aLightIter = aView->ActiveLightIterator(); + } + } + } + else if (anArgCase.IsEqual ("AMB") + || anArgCase.IsEqual ("AMBIENT") + || anArgCase.IsEqual ("AMBLIGHT")) + { + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + addLight (aLightNew, aLayer, isGlobal); + toCreate = Standard_False; + aLightNew = new V3d_AmbientLight(); + } + else if (anArgCase.IsEqual ("DIRECTIONAL") + || anArgCase.IsEqual ("DIRLIGHT")) + { + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + addLight (aLightNew, aLayer, isGlobal); + toCreate = Standard_False; + aLightNew = new V3d_DirectionalLight(); + } + else if (anArgCase.IsEqual ("SPOT") + || anArgCase.IsEqual ("SPOTLIGHT")) + { + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + addLight (aLightNew, aLayer, isGlobal); + toCreate = Standard_False; + aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0)); + } + else if (anArgCase.IsEqual ("POSLIGHT") + || anArgCase.IsEqual ("POSITIONAL")) + { + if (!toCreate) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + addLight (aLightNew, aLayer, isGlobal); + toCreate = Standard_False; + aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0)); + } + else if (anArgCase.IsEqual ("CHANGE") + || anArgCase.IsEqual ("-CHANGE")) + { + if (++anArgIt >= theArgsNb) + { + std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + addLight (aLightNew, aLayer, isGlobal); + aLightNew.Nullify(); const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]); Standard_Integer aLightIt = 0; for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt) @@ -9475,7 +9557,9 @@ static int VLight (Draw_Interpretor& theDi, } } else if (anArgCase.IsEqual ("DEL") - || anArgCase.IsEqual ("DELETE")) + || anArgCase.IsEqual ("DELETE") + || anArgCase.IsEqual ("-DEL") + || anArgCase.IsEqual ("-DELETE")) { Handle(V3d_Light) aLightDel; if (++anArgIt >= theArgsNb) @@ -9495,15 +9579,47 @@ static int VLight (Draw_Interpretor& theDi, break; } } - if (!aLightDel.IsNull()) + if (aLightDel.IsNull()) + { + continue; + } + + TColStd_SequenceOfInteger aLayers; + aViewer->GetAllZLayers (aLayers); + for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next()) + { + if (aLayeriter.Value() == aLayer + || aLayer == Graphic3d_ZLayerId_UNKNOWN) + { + Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value()); + if (!aSettings.Lights().IsNull()) + { + aSettings.Lights()->Remove (aLightDel); + if (aSettings.Lights()->IsEmpty()) + { + aSettings.SetLights (Handle(Graphic3d_LightSet)()); + } + } + aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings); + if (aLayer != Graphic3d_ZLayerId_UNKNOWN) + { + break; + } + } + } + + if (aLayer == Graphic3d_ZLayerId_UNKNOWN) { aViewer->DelLight (aLightDel); } } else if (anArgCase.IsEqual ("COLOR") - || anArgCase.IsEqual ("COLOUR")) + || anArgCase.IsEqual ("COLOUR") + || anArgCase.IsEqual ("-COLOR") + || anArgCase.IsEqual ("-COLOUR")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull()) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; @@ -9512,15 +9628,17 @@ static int VLight (Draw_Interpretor& theDi, TCollection_AsciiString anArgNext (theArgVec[anArgIt]); anArgNext.UpperCase(); const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString()); - if (!aLightCurr.IsNull()) - { - aLightCurr->SetColor (aColor); - } + aLightCurr->SetColor (aColor); } else if (anArgCase.IsEqual ("POS") - || anArgCase.IsEqual ("POSITION")) + || anArgCase.IsEqual ("POSITION") + || anArgCase.IsEqual ("-POS") + || anArgCase.IsEqual ("-POSITION")) { - if ((anArgIt + 3) >= theArgsNb) + if ((anArgIt + 3) >= theArgsNb + || aLightCurr.IsNull() + || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL + && aLightCurr->Type() != Graphic3d_TOLS_SPOT)) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; @@ -9529,28 +9647,17 @@ static int VLight (Draw_Interpretor& theDi, anXYZ[0] = Atof (theArgVec[++anArgIt]); anXYZ[1] = Atof (theArgVec[++anArgIt]); anXYZ[2] = Atof (theArgVec[++anArgIt]); - if (!aLightDir.IsNull()) - { - aLightDir->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); - } - else if (!aLightPos.IsNull()) - { - aLightPos->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); - } - else if (!aLightSpot.IsNull()) - { - aLightSpot->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); - } - else - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } + aLightCurr->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]); } else if (anArgCase.IsEqual ("DIR") - || anArgCase.IsEqual ("DIRECTION")) + || anArgCase.IsEqual ("DIRECTION") + || anArgCase.IsEqual ("-DIR") + || anArgCase.IsEqual ("-DIRECTION")) { - if ((anArgIt + 3) >= theArgsNb) + if ((anArgIt + 3) >= theArgsNb + || aLightCurr.IsNull() + || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL + && aLightCurr->Type() != Graphic3d_TOLS_SPOT)) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; @@ -9559,36 +9666,26 @@ static int VLight (Draw_Interpretor& theDi, anXYZ[0] = Atof (theArgVec[++anArgIt]); anXYZ[1] = Atof (theArgVec[++anArgIt]); anXYZ[2] = Atof (theArgVec[++anArgIt]); - if (!aLightDir.IsNull()) - { - aLightDir->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]); - } - else if (!aLightSpot.IsNull()) - { - aLightSpot->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]); - } - else - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } + aLightCurr->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]); } else if (anArgCase.IsEqual ("SM") - || anArgCase.IsEqual ("SMOOTHNESS")) + || anArgCase.IsEqual ("SMOOTHNESS") + || anArgCase.IsEqual ("-SM") + || anArgCase.IsEqual ("-SMOOTHNESS")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull()) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - Standard_Real aSmoothness = Atof (theArgVec[anArgIt]); - - if (fabs (aSmoothness) < Precision::Confusion()) + Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]); + if (Abs (aSmoothness) <= ShortRealEpsilon()) { aLightCurr->SetIntensity (1.f); } - else if (fabs (aLightCurr->Smoothness()) < Precision::Confusion()) + else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon()) { aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f); } @@ -9598,142 +9695,122 @@ static int VLight (Draw_Interpretor& theDi, aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio)); } - if (!aLightPos.IsNull()) + if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL) { - aLightPos->SetSmoothRadius (aSmoothness); + aLightCurr->SetSmoothRadius (aSmoothness); } - else if (!aLightDir.IsNull()) + else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL) { - aLightDir->SetSmoothAngle (aSmoothness); + aLightCurr->SetSmoothAngle (aSmoothness); } } else if (anArgCase.IsEqual ("INT") - || anArgCase.IsEqual ("INTENSITY")) + || anArgCase.IsEqual ("INTENSITY") + || anArgCase.IsEqual ("-INT") + || anArgCase.IsEqual ("-INTENSITY")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull()) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - Standard_Real aIntensity = Atof (theArgVec[anArgIt]); - - if (!aLightCurr.IsNull()) - { - aLightCurr->SetIntensity (aIntensity); - } + Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]); + aLightCurr->SetIntensity (aIntensity); } else if (anArgCase.IsEqual ("ANG") - || anArgCase.IsEqual ("ANGLE")) + || anArgCase.IsEqual ("ANGLE") + || anArgCase.IsEqual ("-ANG") + || anArgCase.IsEqual ("-ANGLE")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull() + || aLightCurr->Type() != Graphic3d_TOLS_SPOT) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - Standard_Real anAngle = Atof (theArgVec[anArgIt]); - - if (!aLightSpot.IsNull()) - { - aLightSpot->SetAngle (anAngle / 180.0 * M_PI); - } + Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]); + aLightCurr->SetAngle (Standard_ShortReal (anAngle / 180.0 * M_PI)); } else if (anArgCase.IsEqual ("CONSTATTEN") - || anArgCase.IsEqual ("CONSTATTENUATION")) + || anArgCase.IsEqual ("CONSTATTENUATION") + || anArgCase.IsEqual ("-CONSTATTEN") + || anArgCase.IsEqual ("-CONSTATTENUATION")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull() + || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL + && aLightCurr->Type() != Graphic3d_TOLS_SPOT)) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - if (!aLightPos.IsNull()) - { - aLightPos->Attenuation (anAtten[0], anAtten[1]); - anAtten[0] = Atof (theArgVec[anArgIt]); - aLightPos->SetAttenuation (anAtten[0], anAtten[1]); - } - else if (!aLightSpot.IsNull()) - { - aLightSpot->Attenuation (anAtten[0], anAtten[1]); - anAtten[0] = Atof (theArgVec[anArgIt]); - aLightSpot->SetAttenuation (anAtten[0], anAtten[1]); - } - else - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } + aLightCurr->Attenuation (anAtten[0], anAtten[1]); + anAtten[0] = Atof (theArgVec[anArgIt]); + aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]); } else if (anArgCase.IsEqual ("LINATTEN") || anArgCase.IsEqual ("LINEARATTEN") - || anArgCase.IsEqual ("LINEARATTENUATION")) + || anArgCase.IsEqual ("LINEARATTENUATION") + || anArgCase.IsEqual ("-LINATTEN") + || anArgCase.IsEqual ("-LINEARATTEN") + || anArgCase.IsEqual ("-LINEARATTENUATION")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull() + || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL + && aLightCurr->Type() != Graphic3d_TOLS_SPOT)) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - if (!aLightPos.IsNull()) - { - aLightPos->Attenuation (anAtten[0], anAtten[1]); - anAtten[1] = Atof (theArgVec[anArgIt]); - aLightPos->SetAttenuation (anAtten[0], anAtten[1]); - } - else if (!aLightSpot.IsNull()) - { - aLightSpot->Attenuation (anAtten[0], anAtten[1]); - anAtten[1] = Atof (theArgVec[anArgIt]); - aLightSpot->SetAttenuation (anAtten[0], anAtten[1]); - } - else - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } + aLightCurr->Attenuation (anAtten[0], anAtten[1]); + anAtten[1] = Atof (theArgVec[anArgIt]); + aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]); } else if (anArgCase.IsEqual ("EXP") || anArgCase.IsEqual ("EXPONENT") || anArgCase.IsEqual ("SPOTEXP") - || anArgCase.IsEqual ("SPOTEXPONENT")) + || anArgCase.IsEqual ("SPOTEXPONENT") + || anArgCase.IsEqual ("-EXP") + || anArgCase.IsEqual ("-EXPONENT") + || anArgCase.IsEqual ("-SPOTEXP") + || anArgCase.IsEqual ("-SPOTEXPONENT")) { - if (++anArgIt >= theArgsNb) + if (++anArgIt >= theArgsNb + || aLightCurr.IsNull() + || aLightCurr->Type() != Graphic3d_TOLS_SPOT) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - if (!aLightSpot.IsNull()) - { - aLightSpot->SetConcentration (Atof (theArgVec[anArgIt])); - } - else - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } + aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt])); } else if (anArgCase.IsEqual ("HEAD") - || anArgCase.IsEqual ("HEADLIGHT")) + || anArgCase.IsEqual ("HEADLIGHT") + || anArgCase.IsEqual ("-HEAD") + || anArgCase.IsEqual ("-HEADLIGHT")) { - if (++anArgIt >= theArgsNb) + if (aLightCurr.IsNull() + || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT) { std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; return 1; } - if (aLightAmb.IsNull() - && !aLightCurr.IsNull()) + Standard_Boolean isHeadLight = Standard_True; + if (anArgIt + 1 < theArgsNb + && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight)) { - aLightCurr->SetHeadlight (Draw::Atoi (theArgVec[anArgIt]) != 0); - } - else - { - std::cerr << "Wrong syntax at argument '" << anArg << "'!\n"; - return 1; + ++anArgIt; } + aLightCurr->SetHeadlight (isHeadLight); } else { @@ -9741,9 +9818,7 @@ static int VLight (Draw_Interpretor& theDi, } } - addLight (aLightNew, isGlobal); - aViewer->UpdateLights(); - + addLight (aLightNew, aLayer, isGlobal); return 0; } @@ -11930,25 +12005,26 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) theCommands.Add("vlight", "tool to manage light sources, without arguments shows list of lights." "\n Main commands: " - "\n 'clear' to clear lights" - "\n '{def}aults' to load deafault lights" - "\n 'add' (or 'new') to add any light source" + "\n '-clear' to clear lights" + "\n '-{def}aults' to load deafault lights" + "\n '-add' to add any light source" "\n where is one of {amb}ient|directional|{spot}light|positional" "\n 'change' to edit light source with specified lightId" "\n\n In addition to 'add' and 'change' commands you can use light parameters:" - "\n {pos}ition X Y Z" - "\n {dir}ection X Y Z (for directional light or for spotlight)" - "\n color colorName" - "\n {head}light 0|1" - "\n {sm}oothness value" - "\n {int}ensity value" - "\n {constAtten}uation value" - "\n {linearAtten}uation value" - "\n angle angleDeg" - "\n {spotexp}onent value" - "\n local|global" - "\n\n example: vlight add positional head 1 pos 0 1 1 color red" - "\n example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2", + "\n -layer Id" + "\n -{pos}ition X Y Z" + "\n -{dir}ection X Y Z (for directional light or for spotlight)" + "\n -color colorName" + "\n -{head}light 0|1" + "\n -{sm}oothness value" + "\n -{int}ensity value" + "\n -{constAtten}uation value" + "\n -{linearAtten}uation value" + "\n -angle angleDeg" + "\n -{spotexp}onent value" + "\n -local|-global" + "\n\n example: vlight -add positional -head 1 -pos 0 1 1 -color red" + "\n example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2", __FILE__, VLight, group); theCommands.Add("vraytrace", "vraytrace [0|1]" diff --git a/tests/v3d/glsl/phong_pos1 b/tests/v3d/glsl/phong_pos1 index f8d24157bf..f3da39d318 100644 --- a/tests/v3d/glsl/phong_pos1 +++ b/tests/v3d/glsl/phong_pos1 @@ -23,12 +23,13 @@ vdisplay -dispMode 1 f1 f2 vsetlocation f2 $anX 0.001 0 vpoint vl $anX 0 0.001 vfit +vzbufftrihedron # setup light vcaps -ffp 0 vrenderparams -shadingModel phong -vlight clear -vlight add positional pos $anX 0 0.001 color RED1 headLight 0 +vlight -layer default -clear +vlight -layer default -add positional -pos $anX 0 0.001 -color RED1 -headLight 0 set aColor1 [vreadpixel 205 180 rgb name] set aColor2 [vreadpixel 205 220 rgb name] diff --git a/tests/v3d/glsl/phong_pos3 b/tests/v3d/glsl/phong_pos3 new file mode 100644 index 0000000000..ad80e5460a --- /dev/null +++ b/tests/v3d/glsl/phong_pos3 @@ -0,0 +1,46 @@ +puts "========" +puts "0029290: Visualization, TKOpenGl - allow defining Light source per ZLayer" +puts "========" + +pload MODELING VISUALIZATION + +vclear +vclose ALL +vinit View1 -width 1024 -height 768 + +vaxo +vcaps -ffp 0 +vrenderparams -shadingModel phong +vlight clear + +set THE_LIGHTS { + { -1 -1 -1 RED1 } + { 1 -1 -1 YELLOW } + { -1 1 -1 BLUE1 } + { -1 -1 1 CYAN1 } + { 1 1 -1 PURPLE } + { 1 1 1 WHITE } + { -1 1 1 HOTPINK } + { 1 -1 1 GREEN } + { 0 -1 0 MAGENTA1 } + { 0 1 0 MAGENTA3 } +} + +set aLayers [list [vzlayer -add -disable depthClear] [vzlayer -add -disable depthClear] [vzlayer -add -disable depthClear]] +for { set aLayIter 0 } { $aLayIter < 3 } { incr aLayIter } { + set aLayer [lindex $aLayers $aLayIter] + set aShiftX [expr $aLayIter * 4] + psphere s$aLayer 0.5 + vdisplay -dispMode 1 -layer $aLayer s$aLayer + vsetlocation s$aLayer $aShiftX 0 0 + for { set aLightIter 0 } { $aLightIter < 10 } { incr aLightIter } { + set aLight [lindex $THE_LIGHTS $aLightIter] + set aColor [lindex $aLight 3] + set aPos [list [expr $aShiftX + [lindex $aLight 0]] [lindex $aLight 1] [lindex $aLight 2]] + vlight -layer $aLayer -add positional -pos {*}$aPos -color $aColor -headLight 0 + vpoint v${aLayIter}_${aLightIter} {*}$aPos + vdrawtext t${aLayIter}_${aLightIter} "l${aLayIter}_${aLightIter} $aColor" -pos {*}$aPos -color $aColor + } +} +vfit +vdump $::imagedir/${::casename}.png diff --git a/tests/v3d/glsl/phong_pos4 b/tests/v3d/glsl/phong_pos4 new file mode 100644 index 0000000000..6101ace5aa --- /dev/null +++ b/tests/v3d/glsl/phong_pos4 @@ -0,0 +1,35 @@ +puts "========" +puts "0029283: Visualization - allow defining more than 8 light sources" +puts "Test case creates about 100 of light sources." +puts "========" + +pload MODELING VISUALIZATION + +vclear +vclose ALL +vinit View1 +vcaps -ffp 0 +vrenderparams -shadingModel phong +box b -50 5 -50 100 100 100 +vdisplay -dispMode 1 b +vfront +vfit + +# define lights +set THE_COLORS { RED1 YELLOW BLUE1 CYAN1 PURPLE WHITE HOTPINK GREEN MAGENTA1 MAGENTA3 } +vlight clear +set aNbColors 10 +set aLightIndex 0 +set aConstAtten 0.1 +set aLinAtten 1 +set aRand [expr srand(1)] +for { set anZIter -50 } { $anZIter <= 50 } { set anZIter [expr $anZIter + 10] } { + for { set anXIter -50 } { $anXIter <= 50 } { set anXIter [expr $anXIter + 10] } { + set anIndex [expr {int(rand() * $aNbColors)}] + set aColor [lindex $THE_COLORS $anIndex] + set aPos "$anXIter 0 $anZIter" + vlight -add positional -pos {*}$aPos -color $aColor -headLight 0 -constAttenuation $aConstAtten -linearAttenuation $aLinAtten + vpoint v${aLightIndex} {*}$aPos + set aLightIndex [expr $aLightIndex + 1] + } +} diff --git a/tests/v3d/materials/bug24855 b/tests/v3d/materials/bug24855 index 7ae32e91eb..77300fcb31 100644 --- a/tests/v3d/materials/bug24855 +++ b/tests/v3d/materials/bug24855 @@ -12,7 +12,7 @@ vglinfo vsetgradientbg 180 200 255 180 180 180 2 # display shape -vlight change 0 pos -1 1 1 +vlight -change 0 -dir 0.577 -0.577 -0.577 restore $aShape s vsetdispmode 1 vdisplay s diff --git a/tests/v3d/raytrace/bug24130 b/tests/v3d/raytrace/bug24130 index f258d7a261..66bb214d67 100644 --- a/tests/v3d/raytrace/bug24130 +++ b/tests/v3d/raytrace/bug24130 @@ -19,7 +19,7 @@ vdisplay s1 s2 vsetmaterial s1 Silver vsetmaterial s2 Pewter vsetlocation s1 0.0 0.1 0.0 -vlight change 0 pos -1 1 1 +vlight -change 0 -dir 0.577 -0.577 -0.577 vfit # activate ray-tracing diff --git a/tests/v3d/raytrace/bug24819 b/tests/v3d/raytrace/bug24819 index a6524bb942..dbf326047f 100644 --- a/tests/v3d/raytrace/bug24819 +++ b/tests/v3d/raytrace/bug24819 @@ -37,7 +37,7 @@ vmarkerstest mTest 7 -3 0 PointsOnSide=5 MarkerType=5 # 3d text vdrawtext text0 3D_Text -pos 1 2 2 -color 1.0 0.0 0.0 -halign left -valign bottom -angle 0 -zoom 0 -height 20 -aspect regular -font SansFont -vlight change 0 pos -1 1 1 +vlight -change 0 -dir 0.577 -0.577 -0.577 vfit diff --git a/tests/v3d/raytrace/bug25201 b/tests/v3d/raytrace/bug25201 index 0696239f38..6ece7107fe 100644 --- a/tests/v3d/raytrace/bug25201 +++ b/tests/v3d/raytrace/bug25201 @@ -20,7 +20,7 @@ vdisplay s1 s2 vsetmaterial s1 Gold vsetmaterial s2 Silver vsetlocation s1 0.0 0.1 0.0 -vlight change 0 pos -1 1 0.5 +vlight -change 0 -dir 0.667 -0.667 -0.333 vturnview 3.0 -1.2 -0.1 vfit diff --git a/tests/v3d/raytrace/bug26617 b/tests/v3d/raytrace/bug26617 index cb5882a8fb..dfd63de45b 100644 --- a/tests/v3d/raytrace/bug26617 +++ b/tests/v3d/raytrace/bug26617 @@ -24,7 +24,7 @@ vdisplay s1 s2 vsetmaterial s1 Silver vsetmaterial s2 Pewter vsetlocation s1 0.0 0.1 0.0 -vlight change 0 pos -1 1 1 +vlight -change 0 -dir 0.577 -0.577 -0.577 # activate ray-tracing vrenderparams -raytrace diff --git a/tests/v3d/raytrace/refraction b/tests/v3d/raytrace/refraction index c43452dc1d..1576337001 100644 --- a/tests/v3d/raytrace/refraction +++ b/tests/v3d/raytrace/refraction @@ -70,6 +70,6 @@ vsettransparency B3 0.8 vfront vturnview 0 -0.3 0 vfit -vlight change 0 pos 1 1 1 +vlight -change 0 -dir -0.577 -0.577 -0.577 vlight add directional vrenderparams -raytrace -raydepth 5 -shadows off -reflections -fsaa diff --git a/tests/v3d/raytrace/textures b/tests/v3d/raytrace/textures index 67dcc40710..14da6f0315 100644 --- a/tests/v3d/raytrace/textures +++ b/tests/v3d/raytrace/textures @@ -70,6 +70,6 @@ vsetcolor wall2 green vfront vturnview 0 -0.3 0 vfit -vlight change 0 pos 1 1 1 +vlight -change 0 -dir -0.577 -0.577 -0.577 vlight add directional vrenderparams -raytrace -raydepth 3 -shadows on -reflections -fsaa