diff --git a/src/AIS/AIS_InteractiveContext_2.cxx b/src/AIS/AIS_InteractiveContext_2.cxx index 4159a3b5fd..198c5bd82d 100755 --- a/src/AIS/AIS_InteractiveContext_2.cxx +++ b/src/AIS/AIS_InteractiveContext_2.cxx @@ -140,7 +140,6 @@ void AIS_InteractiveContext::CloseLocalContext(const Standard_Integer Index, if(updateproj) myMainSel->UpdateConversion(); else{ - myMainSel->ReactivateProjector(); myMainSel->UpdateSort(); } if(debugmode) @@ -156,11 +155,10 @@ void AIS_InteractiveContext::CloseLocalContext(const Standard_Integer Index, if(GoodIndex==myCurLocalIndex){ myCurLocalIndex = HighestIndex(); const Handle(AIS_LocalContext)& LocCtx = myLocalContexts(myCurLocalIndex); - if(LocCtx->HasSameProjector(VS->Projector())){ - LocCtx->MainSelector()->ReactivateProjector(); - } - else + if (!LocCtx->HasSameProjector (VS->Projector())) + { LocCtx->MainSelector()->UpdateConversion(); + } } else if(debugmode) cout<<"a No Current Local Context WasClosed"< -#include -typedef CALL_DEF_PLANE Graphic3d_CPlane; - -#if defined(__cplusplus) || defined(c_plusplus) -/*==== Definition de Type ====================================================*/ -#include -const Handle(Standard_Type)& TYPE(Graphic3d_CPlane) ; -/*============================================================================*/ - -#endif -#endif /*Graphic3d_CPlane_HeaderFile*/ diff --git a/src/Graphic3d/Graphic3d_CStructure.hxx b/src/Graphic3d/Graphic3d_CStructure.hxx index c00cc3379e..5f96ef877f 100755 --- a/src/Graphic3d/Graphic3d_CStructure.hxx +++ b/src/Graphic3d/Graphic3d_CStructure.hxx @@ -20,6 +20,7 @@ #define _Graphic3d_CStructure_HeaderFile #include +#include class Graphic3d_CStructure { @@ -55,6 +56,7 @@ public: CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence; + Graphic3d_SetOfHClipPlane ClipPlanes; }; ///typedef Graphic3d_CStructure CALL_DEF_STRUCTURE; diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index fc81011d16..93b524d7e1 100755 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -22,6 +22,7 @@ #include #include #include +#include class CALL_DEF_VIEWCONTEXT { @@ -42,9 +43,8 @@ public: Visualization (0), NbActiveLight (0), ActiveLight (NULL), - NbActivePlane (0), - ActivePlane (NULL), - SurfaceDetail (0) + SurfaceDetail (0), + ClipPlanes() { // } @@ -71,12 +71,10 @@ public: int NbActiveLight; CALL_DEF_LIGHT* ActiveLight; - int NbActivePlane; - CALL_DEF_PLANE* ActivePlane; - Handle(Graphic3d_TextureEnv) TextureEnv; int SurfaceDetail; + Graphic3d_SetOfHClipPlane ClipPlanes; }; class Graphic3d_CView diff --git a/src/Graphic3d/Graphic3d_ClipPlane.cxx b/src/Graphic3d/Graphic3d_ClipPlane.cxx new file mode 100644 index 0000000000..f732444029 --- /dev/null +++ b/src/Graphic3d/Graphic3d_ClipPlane.cxx @@ -0,0 +1,251 @@ +// Created on: 2013-07-12 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 65 (the "License") You may not use the content of this file +// except in compliance with the License Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file +// +// The Initial Developer of the Original Code is Open CASCADE SAS, having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement Please see the License for the specific terms +// and conditions governing the rights and limitations under the License + +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE(Graphic3d_ClipPlane, Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ClipPlane, Standard_Transient) + +namespace +{ + static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0; +}; + +// ======================================================================= +// function : Graphic3d_ClipPlane +// purpose : +// ======================================================================= +Graphic3d_ClipPlane::Graphic3d_ClipPlane() +: myEquation (0.0, 0.0, 1.0, 0.0), + myIsOn (Standard_True), + myIsCapping (Standard_False), + myMaterial (Graphic3d_NOM_DEFAULT), + myTexture (NULL), + myHatch (Aspect_HS_HORIZONTAL), + myHatchOn (Standard_False), + myId(), + myEquationMod(0), + myAspectMod(0) +{ + MakeId(); +} + +// ======================================================================= +// function : Graphic3d_ClipPlane +// purpose : +// ======================================================================= +Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation) +: myEquation (theEquation), + myIsOn (Standard_True), + myIsCapping (Standard_False), + myMaterial (Graphic3d_NOM_DEFAULT), + myTexture (NULL), + myHatch (Aspect_HS_HORIZONTAL), + myHatchOn (Standard_False), + myId(), + myEquationMod(0), + myAspectMod(0) +{ + MakeId(); +} + +// ======================================================================= +// function : Graphic3d_ClipPlane +// purpose : +// ======================================================================= +Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther) +: myEquation (theOther.myEquation), + myIsOn (theOther.myIsOn), + myIsCapping (theOther.myIsCapping), + myMaterial (theOther.myMaterial), + myTexture (theOther.myTexture), + myHatch (theOther.myHatch), + myHatchOn (theOther.myHatchOn), + myId(), + myEquationMod (0), + myAspectMod (0) +{ + MakeId(); +} + +// ======================================================================= +// function : Graphic3d_ClipPlane +// purpose : +// ======================================================================= +Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane) +: myEquation (), + myIsOn (Standard_True), + myIsCapping (Standard_False), + myMaterial (Graphic3d_NOM_DEFAULT), + myTexture (NULL), + myHatch (Aspect_HS_HORIZONTAL), + myHatchOn (Standard_False), + myId(), + myEquationMod(0), + myAspectMod(0) +{ + MakeId(); + SetEquation (thePlane); +} + +// ======================================================================= +// function : SetEquation +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation) +{ + myEquation = theEquation; + myEquationMod++; +} + +// ======================================================================= +// function : SetPlane +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane) +{ + thePlane.Coefficients (myEquation[0], + myEquation[1], + myEquation[2], + myEquation[3]); + myEquationMod++; +} + +// ======================================================================= +// function : SetOn +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn) +{ + myIsOn = theIsOn; +} + +// ======================================================================= +// function : SetCapping +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetCapping (const Standard_Boolean theIsOn) +{ + myIsCapping = theIsOn; +} + +// ======================================================================= +// function : ToPlane +// purpose : +// ======================================================================= +gp_Pln Graphic3d_ClipPlane::ToPlane() const +{ + return gp_Pln (myEquation[0], + myEquation[1], + myEquation[2], + myEquation[3]); +} + +// ======================================================================= +// function : Clone +// purpose : +// ======================================================================= +Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane::Clone() const +{ + return new Graphic3d_ClipPlane(*this); +} + +// ======================================================================= +// function : SetCappingMaterial +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetCappingMaterial (const Graphic3d_MaterialAspect& theMat) +{ + myMaterial = theMat; + myAspectMod++; +} + +// ======================================================================= +// function : SetCappingTexture +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture) +{ + myTexture = theTexture; + myAspectMod++; +} + +// ======================================================================= +// function : SetCappingHatch +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle) +{ + myHatch = theStyle; + myAspectMod++; +} + +// ======================================================================= +// function : SetCappingHatchOn +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetCappingHatchOn() +{ + myHatchOn = Standard_True; + myAspectMod++; +} + +// ======================================================================= +// function : SetCappingHatchOff +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::SetCappingHatchOff() +{ + myHatchOn = Standard_False; + myAspectMod++; +} + +// ======================================================================= +// function : MakeId +// purpose : +// ======================================================================= +void Graphic3d_ClipPlane::MakeId() +{ + myId = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name() + + TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER)); +} + +// ======================================================================= +// function : CappingAspect +// purpose : +// ======================================================================= +Handle(Graphic3d_AspectFillArea3d) Graphic3d_ClipPlane::CappingAspect() const +{ + Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); + anAspect->SetDistinguishOff(); + anAspect->SetFrontMaterial (myMaterial); + anAspect->SetTextureMap (myTexture); + anAspect->SetHatchStyle (myHatch); + anAspect->SetInteriorStyle (myHatchOn ? Aspect_IS_HATCH : Aspect_IS_SOLID); + anAspect->SetInteriorColor (myMaterial.Color()); + if (!myTexture.IsNull()) + anAspect->SetTextureMapOn(); + else + anAspect->SetTextureMapOff(); + + return anAspect; +} diff --git a/src/Graphic3d/Graphic3d_ClipPlane.hxx b/src/Graphic3d/Graphic3d_ClipPlane.hxx new file mode 100644 index 0000000000..16e48d044a --- /dev/null +++ b/src/Graphic3d/Graphic3d_ClipPlane.hxx @@ -0,0 +1,228 @@ +// Created on: 2013-07-12 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 65 (the "License") You may not use the content of this file +// except in compliance with the License Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file +// +// The Initial Developer of the Original Code is Open CASCADE SAS, having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement Please see the License for the specific terms +// and conditions governing the rights and limitations under the License + +#ifndef _Graphic3d_ClipPlane_HeaderFile +#define _Graphic3d_ClipPlane_HeaderFile + +#include +#include +#include +#include +#include +#include +#include + +DEFINE_STANDARD_HANDLE (Graphic3d_ClipPlane, Standard_Transient) + +class gp_Pln; +class Graphic3d_AspectFillArea3d; +class Handle(Graphic3d_AspectFillArea3d); + +//! Container for properties describing graphic driver clipping planes. +//! It is up to application to create instances of this class and specify its +//! properties. The instances are passed into graphic driver or other facilities +//! that implement clipping features (e.g. selection). +//! Depending on usage context the class can be used to specify: +//! - Global clipping applied over the whole scene. +//! - Object-level clipping applied for each particular object. +//! Please note that the set of planes can define convex clipping volume. +//! Be aware that number of clip planes supported by OpenGl is implementation +//! dependant: at least 6 planes are available. Thus, take into account +//! number of clipping planes passed for rendering: the object planes plus +//! the view defined ones. +class Graphic3d_ClipPlane : public Standard_Transient +{ +public: + + typedef NCollection_Vec4 Equation; + + //! Default constructor. + //! Initializes clip plane container with the following properties: + //! - Equation (0.0, 0.0, 1.0, 0) + //! - IsOn (True), + //! - IsCapping (False), + //! - Material (Graphic3d_NOM_DEFAULT), + //! - Texture (NULL), + //! - HatchStyle (Aspect_HS_HORIZONTAL), + //! - IsHatchOn (False) + Standard_EXPORT Graphic3d_ClipPlane(); + + //! Copy constructor. + //! @param theOther [in] the copied plane. + Standard_EXPORT Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther); + + //! Construct clip plane for the passed equation. + //! By default the plane is on, capping is turned off. + //! @param theEquation [in] the plane equation. + Standard_EXPORT Graphic3d_ClipPlane (const Equation& theEquation); + + //! Construct clip plane from the passed geomertical definition. + //! By default the plane is on, capping is turned off. + //! @param thePlane [in] the plane. + Standard_EXPORT Graphic3d_ClipPlane (const gp_Pln& thePlane); + + //! Set plane equation by its geometrical definition. + //! @param thePlane [in] the plane. + Standard_EXPORT void SetEquation (const gp_Pln& thePlane); + + //! Set 4-component equation vector for clipping plane. + //! @param theEquation [in] the XYZW (or "ABCD") equation vector. + Standard_EXPORT void SetEquation (const Equation& theEquation); + + //! Get 4-component equation vector for clipping plane. + //! @return clipping plane equation vector. + const Equation& GetEquation() const + { + return myEquation; + } + + //! Check that the clipping plane is turned on. + //! @return boolean flag indicating whether the plane is in on or off state. + Standard_Boolean IsOn() const + { + return myIsOn; + } + + //! Change state of the clipping plane. + //! @param theIsOn [in] the flag specifying whether the graphic driver + //! clipping by this plane should be turned on or off. + Standard_EXPORT void SetOn(const Standard_Boolean theIsOn); + + //! Change state of capping surface rendering. + //! @param theIsOn [in] the flag specifying whether the graphic driver should + //! perform rendering of capping surface produced by this plane. The graphic + //! driver produces this surface for convex graphics by means of stencil-test + //! and multipass rendering. + Standard_EXPORT void SetCapping(const Standard_Boolean theIsOn); + + //! Check state of capping surface rendering. + //! @return true (turned on) or false depending on the state. + Standard_Boolean IsCapping() const + { + return myIsCapping; + } + + //! Get geomertical definition. The plane is built up + //! from the equation clipping plane equation vector. + //! @return geometrical definition of clipping plane. + Standard_EXPORT gp_Pln ToPlane() const; + + //! Clone plane. Virtual method to simplify copying procedure if plane + //! class is redefined at application level to add specific fields to it + //! e.g. id, name, etc. + //! @return new instance of clipping plane with same properties and attributes. + Standard_EXPORT virtual Handle(Graphic3d_ClipPlane) Clone() const; + +public: // @name user-defined graphical attributes + + //! Set material for rendering capping surface. + //! @param theMat [in] the material. + Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat); + + //! @return capping material. + const Graphic3d_MaterialAspect& CappingMaterial() const + { + return myMaterial; + } + + //! Set texture to be applied on capping surface. + //! @param theTexture [in] the texture. + Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture); + + //! @return capping texture map. + const Handle(Graphic3d_TextureMap)& CappingTexture() const + { + return myTexture; + } + + //! Set hatch style (stipple) and turn hatching on. + //! @param theStyle [in] the hatch style. + Standard_EXPORT void SetCappingHatch (const Aspect_HatchStyle theStyle); + + //! @return hatching style. + Aspect_HatchStyle CappingHatch() const + { + return myHatch; + } + + //! Turn on hatching. + Standard_EXPORT void SetCappingHatchOn(); + + //! Turn off hatching. + Standard_EXPORT void SetCappingHatchOff(); + + //! @return True if hatching mask is turned on. + Standard_Boolean IsHatchOn() const + { + return myHatchOn; + } + + //! This ID is used for managing associated resources in graphical driver. + //! The clip plane can be assigned within a range of IO which can be + //! displayed in separate OpenGl contexts. For each of the context an associated + //! OpenGl resource for graphical aspects should be created and kept. + //! The resources are stored in graphical driver for each of individual groups + //! of shared context under the clip plane identifier. + //! @return clip plane resource identifier string. + const TCollection_AsciiString& GetId() const + { + return myId; + } + + //! Compute and return capping apsect from the graphical attributes. + //! @return capping surface rendering aspect. + Standard_EXPORT Handle(Graphic3d_AspectFillArea3d) CappingAspect() const; + +public: // @name modificaton counters + + //! @return modification counter for equation. + unsigned int MCountEquation() const + { + return myEquationMod; + } + + //! @return modification counter for aspect. + unsigned int MCountAspect() const + { + return myAspectMod; + } + +private: + + void MakeId(); + +private: + + Equation myEquation; //!< Plane equation vector. + Standard_Boolean myIsOn; //!< State of the clipping plane. + Standard_Boolean myIsCapping; //!< State of graphic driver capping. + Graphic3d_MaterialAspect myMaterial; //!< Capping surface material. + Handle(Graphic3d_TextureMap) myTexture; //!< Capping surface texture. + Aspect_HatchStyle myHatch; //!< Capping surface hatch mask. + Standard_Boolean myHatchOn; //!< Capping surface hatching flag. + TCollection_AsciiString myId; //!< Resource id. + unsigned int myEquationMod; //!< Modification counter for equation. + unsigned int myAspectMod; //!< Modification counter of aspect. + +public: + + DEFINE_STANDARD_RTTI(Graphic3d_ClipPlane); +}; + +#endif diff --git a/src/Graphic3d/Graphic3d_ClipPlane_Handle.hxx b/src/Graphic3d/Graphic3d_ClipPlane_Handle.hxx new file mode 100644 index 0000000000..db5905a110 --- /dev/null +++ b/src/Graphic3d/Graphic3d_ClipPlane_Handle.hxx @@ -0,0 +1,26 @@ +// Created on: 2013-07-12 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 65 (the "License") You may not use the content of this file +// except in compliance with the License Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file +// +// The Initial Developer of the Original Code is Open CASCADE SAS, having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement Please see the License for the specific terms +// and conditions governing the rights and limitations under the License + +#ifndef _Graphic3d_ClipPlane_Handle_HeaderFile +#define _Graphic3d_ClipPlane_Handle_HeaderFile + +#include +typedef Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane_Handle; + +#endif diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.cdl b/src/Graphic3d/Graphic3d_GraphicDriver.cdl index 0bef557e0c..bc3fbec022 100755 --- a/src/Graphic3d/Graphic3d_GraphicDriver.cdl +++ b/src/Graphic3d/Graphic3d_GraphicDriver.cdl @@ -90,7 +90,8 @@ uses CUserDraw from Graphic3d, NListOfHAsciiString from Graphic3d, FontAspect from Font, - CGraduatedTrihedron from Graphic3d + CGraduatedTrihedron from Graphic3d, + ClipPlane from Graphic3d raises @@ -407,10 +408,11 @@ is is deferred; ---Purpose: call_togl_setlight - SetPlane ( me : mutable; - ACView : CView from Graphic3d ) - is deferred; - ---Purpose: call_togl_setplane + SetClipPlanes (me : mutable; theCView : CView from Graphic3d) is deferred; + ---Purpose: Pass clip planes to the associated graphic driver view. + + SetClipPlanes (me : mutable; theCStructure : CStructure from Graphic3d) is deferred; + ---Purpose: Pass clip planes to the associated graphic driver structure. SetVisualisation ( me : mutable; ACView : CView from Graphic3d ) @@ -952,12 +954,6 @@ is returns Integer from Standard; ---Purpose: call_togl_light - Plane ( myclass; - ACPlane : CPlane from Graphic3d; - Update : Boolean from Standard ) - returns Integer from Standard; - ---Purpose: call_togl_plane - ----------------------------- -- Category: Internal methods ----------------------------- @@ -978,10 +974,6 @@ is ACPick : CPick from Graphic3d; AField : Integer from Standard ); - PrintCPlane ( me; - ACPlane : CPlane from Graphic3d; - AField : Integer from Standard ); - PrintCStructure ( me; ACStructure : CStructure from Graphic3d; AField : Integer from Standard ); diff --git a/src/Graphic3d/Graphic3d_GraphicDriver.cxx b/src/Graphic3d/Graphic3d_GraphicDriver.cxx index 0dea4c027f..942dde55f8 100755 --- a/src/Graphic3d/Graphic3d_GraphicDriver.cxx +++ b/src/Graphic3d/Graphic3d_GraphicDriver.cxx @@ -66,16 +66,6 @@ Standard_Integer Graphic3d_GraphicDriver::Light (const Graphic3d_CLight& ACLight } -Standard_Integer Graphic3d_GraphicDriver::Plane (const Graphic3d_CPlane& ACPlane, const Standard_Boolean Update) { - - static Standard_Integer NbPlanes = 1; - Standard_Boolean Result; - - Result = Update ? ACPlane.PlaneId : NbPlanes++; - return Result; - -} - //-Internal methods, in order void Graphic3d_GraphicDriver::PrintBoolean (const Standard_CString AComment, const Standard_Boolean AValue) const { @@ -135,16 +125,6 @@ void Graphic3d_GraphicDriver::PrintCPick (const Graphic3d_CPick& ACPick, const S } -void Graphic3d_GraphicDriver::PrintCPlane (const Graphic3d_CPlane& ACPlane, const Standard_Integer AField) const { - - if (AField) { - cout << "\tws id " << ACPlane.WsId << ", " - << "view id " << ACPlane.ViewId << "\n"; - cout << flush; - } - -} - void Graphic3d_GraphicDriver::PrintCStructure (const Graphic3d_CStructure& ACStructure, const Standard_Integer AField) const { if (AField) { diff --git a/src/Graphic3d/Graphic3d_MarkerImage.cxx b/src/Graphic3d/Graphic3d_MarkerImage.cxx index 010726516c..4d9a08987c 100644 --- a/src/Graphic3d/Graphic3d_MarkerImage.cxx +++ b/src/Graphic3d/Graphic3d_MarkerImage.cxx @@ -186,7 +186,7 @@ const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImageAlpha() Standard_Byte* anImageRow = myImageAlpha->ChangeRow (aRowIter); for (Standard_Size aColumnIter = 0; aColumnIter < myImage->Width(); aColumnIter++) { - myImage->PixelColor (aColumnIter, aRowIter, anAlpha); + myImage->PixelColor ((Standard_Integer )aColumnIter, (Standard_Integer )aRowIter, anAlpha); anImageRow[aColumnIter] = Standard_Byte (255.0 * anAlpha); } } diff --git a/src/Graphic3d/Graphic3d_SetOfHClipPlane.hxx b/src/Graphic3d/Graphic3d_SetOfHClipPlane.hxx new file mode 100644 index 0000000000..a16dd1cf3c --- /dev/null +++ b/src/Graphic3d/Graphic3d_SetOfHClipPlane.hxx @@ -0,0 +1,30 @@ +// Created on: 2013-07-15 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 65 (the "License") You may not use the content of this file +// except in compliance with the License Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file +// +// The Initial Developer of the Original Code is Open CASCADE SAS, having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement Please see the License for the specific terms +// and conditions governing the rights and limitations under the License + +#ifndef _Graphic3d_SetOfHClipPlane_HeaderFile +#define _Graphic3d_SetOfHClipPlane_HeaderFile + +#include +#include + +// CDL-header shortcut for set of graphical clipping planes. This is a compact +// way (compared to list) to store clippings, with mandatory uniqueness check. +typedef NCollection_Set Graphic3d_SetOfHClipPlane; + +#endif diff --git a/src/Graphic3d/Graphic3d_Structure.cdl b/src/Graphic3d/Graphic3d_Structure.cdl index e062d4a210..a8bac353bd 100755 --- a/src/Graphic3d/Graphic3d_Structure.cdl +++ b/src/Graphic3d/Graphic3d_Structure.cdl @@ -74,7 +74,8 @@ uses Vector from Graphic3d, Vertex from Graphic3d, TransModeFlags from Graphic3d, - Pnt from gp + Pnt from gp, + SetOfHClipPlane from Graphic3d raises @@ -270,6 +271,15 @@ is ---Purpose: Get Z layer ID of displayed structure. The method -- returns -1 if the structure has no ID (deleted from graphic driver). + SetClipPlanes (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is static; + ---Purpose: Changes a set of clip planes slicing the structure on rendering. + -- @param thePlanes [in] the set of clip planes. + + GetClipPlanes (me) returns SetOfHClipPlane from Graphic3d; + ---C++: return const& + ---Purpose: Get clip planes slicing the structure on rendering. + -- @return set of clip planes. + SetPick ( me : mutable; AValue : Boolean from Standard ) is static; diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index 87ba9e8b25..702c6863dc 100755 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -2460,7 +2460,6 @@ Standard_Boolean Graphic3d_Structure::HLRValidation () const { //function : CStructure //purpose : //======================================================================= - Graphic3d_CStructure* Graphic3d_Structure::CStructure() { return &MyCStructure; @@ -2470,7 +2469,6 @@ Graphic3d_CStructure* Graphic3d_Structure::CStructure() //function : SetZLayer //purpose : //======================================================================= - void Graphic3d_Structure::SetZLayer (const Standard_Integer theLayerId) { // if the structure is not displayed, unable to change its display layer @@ -2484,8 +2482,26 @@ void Graphic3d_Structure::SetZLayer (const Standard_Integer theLayerId) //function : GetZLayer //purpose : //======================================================================= - Standard_Integer Graphic3d_Structure::GetZLayer () const { return MyStructureManager->GetZLayer (this); } + +//======================================================================= +//function : SetClipPlanes +//purpose : +//======================================================================= +void Graphic3d_Structure::SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes) +{ + MyCStructure.ClipPlanes = thePlanes; + MyGraphicDriver->SetClipPlanes (MyCStructure); +} + +//======================================================================= +//function : GetClipPlanes +//purpose : +//======================================================================= +const Graphic3d_SetOfHClipPlane& Graphic3d_Structure::GetClipPlanes() const +{ + return MyCStructure.ClipPlanes; +} diff --git a/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx b/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx index 9eeb99bbfd..3218bb30e6 100755 --- a/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx +++ b/src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx @@ -35,27 +35,6 @@ typedef struct { } CALL_DEF_VERTEX; - -/* MODELE CLIPPING */ - -typedef struct { - - int WsId; - - int ViewId; - - int PlaneId; - - int Active; - - float CoefA; - float CoefB; - float CoefC; - float CoefD; - -} CALL_DEF_PLANE; - - /* SOURCE LUMINEUSE */ typedef struct { diff --git a/src/MeshVS/MeshVS_DummySensitiveEntity.cdl b/src/MeshVS/MeshVS_DummySensitiveEntity.cdl index d94a9bea19..9ac80a4b03 100755 --- a/src/MeshVS/MeshVS_DummySensitiveEntity.cdl +++ b/src/MeshVS/MeshVS_DummySensitiveEntity.cdl @@ -27,7 +27,7 @@ class DummySensitiveEntity from MeshVS inherits SensitiveEntity from SelectBasic uses EntityOwner from SelectBasics, ListOfBox2d from SelectBasics, - + PickArgs from SelectBasics, Array1OfPnt2d from TColgp, Box2d from Bnd @@ -38,9 +38,10 @@ is Areas ( me: mutable; aresult: in out ListOfBox2d from SelectBasics ) is redefined; - Matches ( me: mutable; - X, Y, aTol: Real; - DMin: out Real ) returns Boolean is redefined; + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined; Matches ( me: mutable; XMin, YMin, XMax, YMax, aTol: Real ) returns Boolean is redefined; diff --git a/src/MeshVS/MeshVS_DummySensitiveEntity.cxx b/src/MeshVS/MeshVS_DummySensitiveEntity.cxx index 967c2e5326..b002101d02 100755 --- a/src/MeshVS/MeshVS_DummySensitiveEntity.cxx +++ b/src/MeshVS/MeshVS_DummySensitiveEntity.cxx @@ -42,9 +42,8 @@ void MeshVS_DummySensitiveEntity::Areas( SelectBasics_ListOfBox2d& ) // Function : Matches // Purpose : //================================================================ -Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const Standard_Real, - const Standard_Real, - const Standard_Real, +Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const SelectBasics_PickArgs&, + Standard_Real&, Standard_Real& ) { return Standard_False; diff --git a/src/MeshVS/MeshVS_SensitiveMesh.cdl b/src/MeshVS/MeshVS_SensitiveMesh.cdl index 2065ad2349..873bfb1334 100755 --- a/src/MeshVS/MeshVS_SensitiveMesh.cdl +++ b/src/MeshVS/MeshVS_SensitiveMesh.cdl @@ -30,7 +30,8 @@ uses Box2d from Bnd, Location from TopLoc, Lin from gp, - ListOfBox2d from SelectBasics, + ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Projector from Select3D is @@ -42,15 +43,12 @@ is GetConnected( me: mutable; aLocation : Location from TopLoc ) returns SensitiveEntity from Select3D is redefined; - - ComputeDepth( me; EyeLine : Lin from gp ) returns Real from Standard - is redefined; - - Matches( me: mutable; X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard ) returns Boolean - is redefined; - + + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined; + Matches ( me: mutable; XMin, YMin, XMax, YMax : Real; aTol : Real ) returns Boolean is redefined; diff --git a/src/MeshVS/MeshVS_SensitiveMesh.cxx b/src/MeshVS/MeshVS_SensitiveMesh.cxx index 0a094a66b9..a9f715a40b 100755 --- a/src/MeshVS/MeshVS_SensitiveMesh.cxx +++ b/src/MeshVS/MeshVS_SensitiveMesh.cxx @@ -60,13 +60,13 @@ Standard_Integer MeshVS_SensitiveMesh::GetMode () const // name : Matches // Purpose : //======================================================================= -Standard_Boolean MeshVS_SensitiveMesh::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean MeshVS_SensitiveMesh::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { - DMin = 0.; - + theMatchDMin = 0.0; + theMatchDepth = Precision::Infinite(); + Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() ); if( anOwner.IsNull() ) return Standard_False; Handle(MeshVS_Mesh) aMeshPrs = Handle(MeshVS_Mesh)::DownCast( anOwner->Selectable() ); @@ -75,12 +75,17 @@ Standard_Boolean MeshVS_SensitiveMesh::Matches(const Standard_Real X, if( aDS.IsNull() ) return Standard_False; Handle(TColStd_HPackedMapOfInteger) NodesMap; Handle(TColStd_HPackedMapOfInteger) ElemsMap; + // Mesh data source should provide the algorithm for computation // of detected entities from 2D point - Standard_Boolean isDetected = aDS->GetDetectedEntities( aMeshPrs, X, Y, aTol, NodesMap, ElemsMap, DMin ); + Standard_Boolean isDetected = + aDS->GetDetectedEntities (aMeshPrs, thePickArgs.X(), thePickArgs.Y(), + thePickArgs.Tolerance(), NodesMap, + ElemsMap, theMatchDMin); + // The detected entites will be available from mesh owner anOwner->SetDetectedEntities( NodesMap, ElemsMap ); - + return isDetected; } @@ -148,15 +153,6 @@ Handle(Select3D_SensitiveEntity) MeshVS_SensitiveMesh::GetConnected( const TopLo return aMeshEnt; } -//======================================================================= -//function : ComputeDepth -//purpose : -//======================================================================= -Standard_Real MeshVS_SensitiveMesh::ComputeDepth( const gp_Lin& /*EyeLine*/ ) const -{ - return Precision::Infinite(); -} - //================================================== // Function: ProjectOneCorner // Purpose : @@ -181,8 +177,6 @@ void MeshVS_SensitiveMesh::ProjectOneCorner(const Handle(Select3D_Projector)& th //================================================== void MeshVS_SensitiveMesh::Project(const Handle(Select3D_Projector)& aProj) { - Select3D_SensitiveEntity::Project(aProj); // to set the field last proj... - mybox2d.SetVoid(); if (mybox.IsVoid()) return; diff --git a/src/MeshVS/MeshVS_SensitivePolyhedron.cdl b/src/MeshVS/MeshVS_SensitivePolyhedron.cdl index e9091ec9df..906ce670eb 100755 --- a/src/MeshVS/MeshVS_SensitivePolyhedron.cdl +++ b/src/MeshVS/MeshVS_SensitivePolyhedron.cdl @@ -31,6 +31,7 @@ uses Box2d from Bnd, Lin from gp, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt from TColgp, HArray1OfPnt from TColgp, HArray1OfPnt2d from TColgp, @@ -47,10 +48,10 @@ is GetConnected( me:mutable; aLocation: Location from TopLoc ) returns SensitiveEntity from Select3D is redefined; - Matches( me : mutable; - X,Y : Real from Standard; - aTol : Real from Standard; - DMin : out Real from Standard ) returns Boolean is redefined; + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined; Matches( me : mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -66,7 +67,7 @@ is FindIntersection( me; NodesIndices : SequenceOfInteger from TColStd; EyeLine : Lin from gp ) returns Real is protected; - ComputeDepth( me; EyeLine: Lin from gp ) returns Real from Standard is redefined; + ComputeDepth( me; EyeLine: Lin from gp ) returns Real from Standard is virtual; -- ComputeSize( me ) returns Real from Standard is redefined; diff --git a/src/MeshVS/MeshVS_SensitivePolyhedron.cxx b/src/MeshVS/MeshVS_SensitivePolyhedron.cxx index 847d0b61cc..bf767c6b0c 100755 --- a/src/MeshVS/MeshVS_SensitivePolyhedron.cxx +++ b/src/MeshVS/MeshVS_SensitivePolyhedron.cxx @@ -33,7 +33,7 @@ MeshVS_SensitivePolyhedron:: MeshVS_SensitivePolyhedron( const Handle( SelectBasics_EntityOwner )& Owner, const TColgp_Array1OfPnt& Nodes, const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo ) -: Select3D_SensitiveEntity( Owner ), +: Select3D_SensitiveEntity( Owner ), myTopo( Topo ) { Standard_Integer low = Nodes.Lower(), up = Nodes.Upper(), i; @@ -51,8 +51,6 @@ MeshVS_SensitivePolyhedron( const Handle( SelectBasics_EntityOwner )& Owner, //================================================================ void MeshVS_SensitivePolyhedron::Project( const Handle(Select3D_Projector)& aProjector ) { - Select3D_SensitiveEntity::Project( aProjector ); - if( myNodes.IsNull() || myNodes2d.IsNull() ) return; @@ -115,10 +113,9 @@ void sort( Standard_Real& a, Standard_Real& b ) // Function : Matches // Purpose : //================================================================ -Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin ) +Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const SelectBasics_PickArgs& thePickArgs, + Standard_Real& /*theMatchDMin*/, + Standard_Real& theMatchDepth ) { if( myNodes2d.IsNull() || myTopo.IsNull() ) return Standard_False; @@ -127,7 +124,7 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X, R2 = myTopo->Upper(), low = myNodes2d->Lower(); - Standard_Real rTol = aTol*SensitivityFactor(); + Standard_Real rTol = thePickArgs.Tolerance() * SensitivityFactor(); Standard_Boolean inside = Standard_False; @@ -149,15 +146,15 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X, y2 = myNodes2d->Value( low+next ).Y(); if( Abs( x2-x1 )=y1-rTol && Y<=y2+rTol && x1>X-rTol ) + if ( thePickArgs.Y() >= y1 - rTol && thePickArgs.Y() <= y2 + rTol && x1 > thePickArgs.X() - rTol ) intersect++; } else - { + { //inclined edge!!! k = ( y2-y1 ) / ( x2-x1 ); @@ -165,9 +162,9 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X, if( Abs( k )>Precision::Confusion() ) { - xp = ( Y-b ) / k; // absciss of point of intersection + xp = ( thePickArgs.Y() - b ) / k; // absciss of point of intersection sort( x1, x2 ); - if( xp>=x1 && xp<=x2 && xp>X-rTol ) + if( xp >= x1 && xp <= x2 && xp > thePickArgs.X() - rTol ) intersect++; } } @@ -177,8 +174,11 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X, if( inside ) { - return Select3D_SensitiveEntity::Matches( X, Y, aTol, DMin ); + theMatchDepth = ComputeDepth (thePickArgs.PickLine()); + + return !thePickArgs.IsClipped(theMatchDepth); } + return Standard_False; } @@ -226,7 +226,7 @@ Standard_Real MeshVS_SensitivePolyhedron::FindIntersection { Standard_Real val( Precision::Infinite() ); for( Standard_Integer i=1, n=NodesIndices.Length(); i<=n; i++ ) - val = Min( val, ElCLib::Parameter( + val = Min( val, ElCLib::Parameter( EyeLine, myNodes->Value( myNodes->Lower()+NodesIndices.Value( i ) ) ) ); return val; @@ -265,7 +265,7 @@ Standard_Real MeshVS_SensitivePolyhedron::ComputeDepth( const gp_Lin& EyeLine ) // Function : Areas // Purpose : //================================================================ -void MeshVS_SensitivePolyhedron::Areas( SelectBasics_ListOfBox2d& aResult ) +void MeshVS_SensitivePolyhedron::Areas( SelectBasics_ListOfBox2d& aResult ) { Bnd_Box2d aBox; GetBox2d( aBox ); diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index 9e596aede7..65ba3e5a06 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -114,3 +114,11 @@ OpenGl_Vec.hxx OpenGl_VertexBuffer.hxx OpenGl_VertexBuffer.cxx OpenGl_VertexBufferEditor.hxx +OpenGl_RenderFilter.hxx +OpenGl_RenderFilter.cxx +OpenGl_CappingAlgo.hxx +OpenGl_CappingAlgo.cxx +OpenGl_CappingPlaneResource.hxx +OpenGl_CappingPlaneResource.cxx +OpenGl_ClippingState.hxx +OpenGl_ClippingState.cxx diff --git a/src/OpenGl/OpenGl_AspectFace.cxx b/src/OpenGl/OpenGl_AspectFace.cxx index b5c5b16b96..428620d182 100644 --- a/src/OpenGl/OpenGl_AspectFace.cxx +++ b/src/OpenGl/OpenGl_AspectFace.cxx @@ -25,6 +25,10 @@ #include #include #include +#include +#include + +#include namespace { @@ -256,6 +260,145 @@ void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)& theContext, myAspectEdge.SetContext (anEdgeContext); } +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)& theContext, + const Handle(Graphic3d_AspectFillArea3d)& theAspect) +{ + CALL_DEF_CONTEXTFILLAREA aCAspect; + Standard_Real aWidth; + Quantity_Color aBackIntColor; + Quantity_Color aEdgeColor; + Aspect_TypeOfLine aLType; + Quantity_Color aIntColor; + Aspect_InteriorStyle aIntStyle; + NCollection_Vec3 aColor; + + theAspect->Values (aIntStyle, aIntColor, aBackIntColor, aEdgeColor, aLType, aWidth); + aIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB); + + aCAspect.Style = int (aIntStyle); + aCAspect.IntColor.r = float (aColor.r()); + aCAspect.IntColor.g = float (aColor.g()); + aCAspect.IntColor.b = float (aColor.b()); + + if (theAspect->Distinguish()) + { + aBackIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB); + } + + aCAspect.BackIntColor.r = float (aColor.r()); + aCAspect.BackIntColor.g = float (aColor.g()); + aCAspect.BackIntColor.b = float (aColor.b()); + + aCAspect.Edge = theAspect->Edge () ? 1:0; + aEdgeColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB); + + aCAspect.EdgeColor.r = float (aColor.r()); + aCAspect.EdgeColor.g = float (aColor.g()); + aCAspect.EdgeColor.b = float (aColor.b()); + aCAspect.LineType = int (aLType); + aCAspect.Width = float (aWidth); + aCAspect.Hatch = int (theAspect->HatchStyle ()); + + aCAspect.Distinguish = theAspect->Distinguish () ? 1:0; + aCAspect.BackFace = theAspect->BackFace () ? 1:0; + + aCAspect.Back.Shininess = float ((theAspect->BackMaterial ()).Shininess ()); + aCAspect.Back.Ambient = float ((theAspect->BackMaterial ()).Ambient ()); + aCAspect.Back.Diffuse = float ((theAspect->BackMaterial ()).Diffuse ()); + aCAspect.Back.Specular = float ((theAspect->BackMaterial ()).Specular ()); + aCAspect.Back.Transparency = float ((theAspect->BackMaterial ()).Transparency ()); + aCAspect.Back.Emission = float ((theAspect->BackMaterial ()).Emissive ()); + + // Reflection mode + aCAspect.Back.IsAmbient = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0 ); + aCAspect.Back.IsDiffuse = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0 ); + aCAspect.Back.IsSpecular = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0 ); + aCAspect.Back.IsEmission = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0 ); + + // Material type + const Graphic3d_MaterialAspect aBackMat = theAspect->BackMaterial (); + Standard_Boolean isBackPhys = aBackMat.MaterialType (Graphic3d_MATERIAL_PHYSIC); + aCAspect.Back.IsPhysic = (isBackPhys ? 1 : 0 ); + + // Specular Color + aCAspect.Back.ColorSpec.r = float (((theAspect->BackMaterial ()).SpecularColor ()).Red ()); + aCAspect.Back.ColorSpec.g = float (((theAspect->BackMaterial ()).SpecularColor ()).Green ()); + aCAspect.Back.ColorSpec.b = float (((theAspect->BackMaterial ()).SpecularColor ()).Blue ()); + + // Ambient color + aCAspect.Back.ColorAmb.r = float (((theAspect->BackMaterial ()).AmbientColor ()).Red ()); + aCAspect.Back.ColorAmb.g = float (((theAspect->BackMaterial ()).AmbientColor ()).Green ()); + aCAspect.Back.ColorAmb.b = float (((theAspect->BackMaterial ()).AmbientColor ()).Blue ()); + + // Diffuse color + aCAspect.Back.ColorDif.r = float (((theAspect->BackMaterial ()).DiffuseColor ()).Red ()); + aCAspect.Back.ColorDif.g = float (((theAspect->BackMaterial ()).DiffuseColor ()).Green ()); + aCAspect.Back.ColorDif.b = float (((theAspect->BackMaterial ()).DiffuseColor ()).Blue ()); + + // Emissive color + aCAspect.Back.ColorEms.r = float (((theAspect->BackMaterial ()).EmissiveColor ()).Red ()); + aCAspect.Back.ColorEms.g = float (((theAspect->BackMaterial ()).EmissiveColor ()).Green ()); + aCAspect.Back.ColorEms.b = float (((theAspect->BackMaterial ()).EmissiveColor ()).Blue ()); + + aCAspect.Back.EnvReflexion = float ((theAspect->BackMaterial ()).EnvReflexion()); + + aCAspect.Front.Shininess = float ((theAspect->FrontMaterial ()).Shininess ()); + aCAspect.Front.Ambient = float ((theAspect->FrontMaterial ()).Ambient ()); + aCAspect.Front.Diffuse = float ((theAspect->FrontMaterial ()).Diffuse ()); + aCAspect.Front.Specular = float ((theAspect->FrontMaterial ()).Specular ()); + aCAspect.Front.Transparency = float ((theAspect->FrontMaterial ()).Transparency ()); + aCAspect.Front.Emission = float ((theAspect->FrontMaterial ()).Emissive ()); + + // Reflection mode + aCAspect.Front.IsAmbient = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0); + aCAspect.Front.IsDiffuse = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0); + aCAspect.Front.IsSpecular = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0); + aCAspect.Front.IsEmission = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0); + + // Materail type + const Graphic3d_MaterialAspect aFrontMat = theAspect->FrontMaterial (); + Standard_Boolean isFrontPhys = aFrontMat.MaterialType (Graphic3d_MATERIAL_PHYSIC); + aCAspect.Front.IsPhysic = (isFrontPhys ? 1 : 0 ); + + // Specular Color + aCAspect.Front.ColorSpec.r = float (((theAspect->FrontMaterial ()).SpecularColor ()).Red ()); + aCAspect.Front.ColorSpec.g = float (((theAspect->FrontMaterial ()).SpecularColor ()).Green ()); + aCAspect.Front.ColorSpec.b = float (((theAspect->FrontMaterial ()).SpecularColor ()).Blue ()); + + // Ambient color + aCAspect.Front.ColorAmb.r = float (((theAspect->FrontMaterial ()).AmbientColor ()).Red ()); + aCAspect.Front.ColorAmb.g = float (((theAspect->FrontMaterial ()).AmbientColor ()).Green ()); + aCAspect.Front.ColorAmb.b = float (((theAspect->FrontMaterial ()).AmbientColor ()).Blue ()); + + // Diffuse color + aCAspect.Front.ColorDif.r = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Red ()); + aCAspect.Front.ColorDif.g = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Green ()); + aCAspect.Front.ColorDif.b = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Blue ()); + + // Emissive color + aCAspect.Front.ColorEms.r = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Red ()); + aCAspect.Front.ColorEms.g = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Green ()); + aCAspect.Front.ColorEms.b = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Blue ()); + + aCAspect.Front.EnvReflexion = float ((theAspect->FrontMaterial ()).EnvReflexion()); + aCAspect.IsDef = 1; + aCAspect.Texture.TextureMap = theAspect->TextureMap(); + aCAspect.Texture.doTextureMap = theAspect->TextureMapState() ? 1 : 0; + + Standard_Integer aPolyMode; + Standard_ShortReal aPolyFactor, aPolyUnits; + theAspect->PolygonOffsets (aPolyMode, aPolyFactor, aPolyUnits); + aCAspect.PolygonOffsetMode = aPolyMode; + aCAspect.PolygonOffsetFactor = (Standard_ShortReal)aPolyFactor; + aCAspect.PolygonOffsetUnits = (Standard_ShortReal)aPolyUnits; + + Init (theContext, aCAspect); +} + // ======================================================================= // function : Render // purpose : diff --git a/src/OpenGl/OpenGl_AspectFace.hxx b/src/OpenGl/OpenGl_AspectFace.hxx index 7dbb2bf071..198c08ec91 100644 --- a/src/OpenGl/OpenGl_AspectFace.hxx +++ b/src/OpenGl/OpenGl_AspectFace.hxx @@ -24,10 +24,10 @@ #include #include #include - #include #include #include +#include #define OPENGL_AMBIENT_MASK (1<<0) #define OPENGL_DIFFUSE_MASK (1<<1) @@ -57,6 +57,9 @@ public: void Init (const Handle(OpenGl_Context)& theContext, const CALL_DEF_CONTEXTFILLAREA& theAspect); + void Init (const Handle(OpenGl_Context)& theContext, + const Handle(Graphic3d_AspectFillArea3d)& theAspect); + void SetAspectEdge (const OpenGl_AspectLine* theAspectEdge) { myAspectEdge = *theAspectEdge; } const OpenGl_AspectLine* AspectEdge() const { return &myAspectEdge; } diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx new file mode 100644 index 0000000000..3340a97b8c --- /dev/null +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -0,0 +1,284 @@ +// Created on: 2013-09-05 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#include +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter) + +Handle(OpenGl_RenderFilter) OpenGl_CappingAlgo::myRenderFilter; +OpenGl_AspectFace OpenGl_CappingAlgo::myFrontCulling; +OpenGl_AspectFace OpenGl_CappingAlgo::myNoneCulling; +Standard_Boolean OpenGl_CappingAlgo::myIsInit = Standard_False; + +namespace +{ + static const OpenGl_Vec4 THE_CAPPING_PLN_VERTS[12] = + { OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f), + OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f), + OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) }; + + static const OpenGl_Vec4 THE_CAPPING_PLN_TCOORD[12] = + { OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f), + OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f), + OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f), + OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) }; +}; + +// ======================================================================= +// function : RenderCapping +// purpose : +// ======================================================================= +void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_ListOfGroup& theGroups) +{ + // do not draw capping surface for second transparency pass + if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSDO) + return; + + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); + + // check whether algorithm need to be runned + Standard_Boolean isCapping = Standard_False; + Graphic3d_SetOfHClipPlane aContextPlanes = aContext->Clipping().Planes(); + Graphic3d_SetOfHClipPlane::Iterator aCappingIt (aContextPlanes); + for (; aCappingIt.More(); aCappingIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value(); + if (aPlane->IsCapping()) + { + isCapping = Standard_True; + break; + } + } + + // do not perform algorithm is there is nothing to render + if (!isCapping) + return; + + // init internal data + Init(); + + // remember current aspect face defined in workspace + const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace (Standard_False); + + // replace primitive groups rendering filter + static Handle(OpenGl_CappingAlgoFilter) aCappingFilter = new OpenGl_CappingAlgoFilter(); + Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter(); + theWorkspace->SetRenderFilter (aCappingFilter); + + // prepare for rendering the clip planes + glEnable (GL_STENCIL_TEST); + + // generate capping for every clip plane + for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) + { + // get plane being rendered + const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value(); + if (!aRenderPlane->IsCapping()) + { + continue; + } + + // enable only the rendering plane to generate stencil mask + Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (aContextPlanes); + for (; aPlaneIt.More(); aPlaneIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); + const Standard_Boolean isOn = (aPlane == aRenderPlane); + aContext->ChangeClipping().SetEnabled (aPlane, isOn); + } + + glClear (GL_STENCIL_BUFFER_BIT); + glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + // override aspects, disable culling + theWorkspace->SetAspectFace (NoneCulling()); + theWorkspace->AspectFace (Standard_True); + + // evaluate number of pair faces + glDisable (GL_DEPTH_TEST); + glDepthMask (GL_FALSE); + glStencilFunc (GL_ALWAYS, 1, 0x01); + glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT); + + OpenGl_ListOfGroup::Iterator aGroupIt (theGroups); + for (; aGroupIt.More(); aGroupIt.Next()) + { + aGroupIt.Value()->Render (theWorkspace); + } + + // override material, cull backfaces + theWorkspace->SetAspectFace (FrontCulling()); + theWorkspace->AspectFace (Standard_True); + + // enable all clip plane except the rendered one + for (aPlaneIt.Init (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); + const Standard_Boolean isOn = (aPlane != aRenderPlane); + aContext->ChangeClipping().SetEnabled (aPlane, isOn); + } + + // render capping plane using the generated stencil mask + glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthMask (GL_TRUE); + glDepthFunc (GL_LESS); + glStencilFunc (GL_EQUAL, 1, 0x01); + glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); + glEnable (GL_DEPTH_TEST); + + RenderPlane (theWorkspace, aRenderPlane); + } + + // restore previous application state + glClear (GL_STENCIL_BUFFER_BIT); + glStencilFunc (GL_ALWAYS, 0, 0xFF); + glDisable (GL_STENCIL_TEST); + + // enable clipping + for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) + { + aContext->ChangeClipping().SetEnabled (aCappingIt.Value(), Standard_True); + } + + // restore rendering aspects + theWorkspace->SetAspectFace (aFaceAsp); + theWorkspace->SetRenderFilter (aRenderFilter); +} + +// ======================================================================= +// function : RenderPlane +// purpose : +// ======================================================================= +void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace, + const Handle(Graphic3d_ClipPlane)& thePlane) +{ + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); + + // get resource for the plane + TCollection_AsciiString aResId = thePlane->GetId(); + + Handle(OpenGl_CappingPlaneResource) aPlaneRes; + if (!aContext->GetResource (aResId, aPlaneRes)) + { + // share and register for release once the resource is no longer used + aPlaneRes = new OpenGl_CappingPlaneResource (thePlane); + aContext->ShareResource (aResId, aPlaneRes); + } + + aPlaneRes->Update (aContext); + + const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace (Standard_False); + const OpenGl_AspectFace* aPlaneAspect = aPlaneRes->AspectFace(); + if (aPlaneAspect != NULL) + { + theWorkspace->SetAspectFace (aPlaneAspect); + } + + // apply aspect for rendering + theWorkspace->AspectFace (Standard_True); + + // set identity model matrix + const OpenGl_Matrix* aModelMatrix = theWorkspace->SetStructureMatrix (&OpenGl_IdentityMatrix); + + glMultMatrixf ((const GLfloat*)aPlaneRes->Orientation()); + glNormal3f (0.0f, 1.0f, 0.0f); + glEnableClientState (GL_VERTEX_ARRAY); + glVertexPointer (4, GL_FLOAT, 0, (GLfloat* )&THE_CAPPING_PLN_VERTS); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer (4, GL_FLOAT, 0, (GLfloat*)&THE_CAPPING_PLN_TCOORD); + glDrawArrays (GL_TRIANGLES, 0, 12); + glDisableClientState (GL_VERTEX_ARRAY); + glDisableClientState (GL_TEXTURE_COORD_ARRAY); + + theWorkspace->SetStructureMatrix (aModelMatrix); + theWorkspace->SetAspectFace (aFaceAspect); + + // set delayed resource release + aPlaneRes.Nullify(); + aContext->ReleaseResource (aResId, Standard_True); +} + +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +void OpenGl_CappingAlgo::Init() +{ + if (myIsInit) + return; + + myRenderFilter = new OpenGl_CappingAlgoFilter(); + myNoneCulling.CullingMode = TelCullNone; + myNoneCulling.Edge = 0; + + myFrontCulling.CullingMode = TelCullBack; + myFrontCulling.Edge = 0; + + myIsInit = Standard_True; +} + +// ======================================================================= +// function : CanRender +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement) +{ + const OpenGl_PrimitiveArray* aPArray = + dynamic_cast (theElement); + if (!aPArray) + return Standard_False; + + switch (aPArray->PArray()->type) + { + case TelPolygonsArrayType : + case TelTrianglesArrayType : + case TelQuadranglesArrayType : + case TelTriangleStripsArrayType : + case TelQuadrangleStripsArrayType : + case TelTriangleFansArrayType : + return Standard_True; + + default: + return Standard_False; + } +} diff --git a/src/OpenGl/OpenGl_CappingAlgo.hxx b/src/OpenGl/OpenGl_CappingAlgo.hxx new file mode 100644 index 0000000000..a51cfb5153 --- /dev/null +++ b/src/OpenGl/OpenGl_CappingAlgo.hxx @@ -0,0 +1,92 @@ +// Created on: 2013-09-05 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _OpenGl_CappingAlgo_H__ +#define _OpenGl_CappingAlgo_H__ + +#include +#include + +// Forward declaration +class Handle(OpenGl_Workspace); +class Handle(Graphic3d_ClipPlane); + +DEFINE_STANDARD_HANDLE (OpenGl_CappingAlgoFilter, OpenGl_RenderFilter) + +//! Capping surface rendering algorithm. +class OpenGl_CappingAlgo +{ +public: + + //! Draw capping surfaces by OpenGl for the clipping planes + //! enabled in current context state. Depth buffer must be generated + //! for the passed groups. + //! @param theWorkspace [in] the GL workspace, context state. + //! @param theGroups [in] the group of primitives to be capped. + Standard_EXPORT static void RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_ListOfGroup& theGroups); + + //! Render infinite capping plane. + //! @param theWorkspace [in] the GL workspace, context state. + //! @param thePlane [in] the graphical plane, for which the capping surface is rendered. + Standard_EXPORT static void RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace, + const Handle(Graphic3d_ClipPlane)& thePlane); + +private: + + //! Init algorithm. + static void Init(); + + //! @return capping algorithm rendering filter. + static const Handle(OpenGl_RenderFilter)& CappingFilter() { return myRenderFilter; } + + //! @return face aspect for front face culling mode. + static const OpenGl_AspectFace* FrontCulling() { return &myFrontCulling; } + + //! @return face aspect for none culling mode. + static const OpenGl_AspectFace* NoneCulling() { return &myNoneCulling; } + +private: + + static Handle(OpenGl_RenderFilter) myRenderFilter; + static OpenGl_AspectFace myFrontCulling; + static OpenGl_AspectFace myNoneCulling; + static Standard_Boolean myIsInit; +}; + +//! Graphical capping rendering algorithm filter. +//! Filters out everything excepth shaded primitives. +class OpenGl_CappingAlgoFilter : public OpenGl_RenderFilter +{ +public: + + //! Default constructor. + OpenGl_CappingAlgoFilter() {} + + //! Checks whether the element can be rendered or not. + //! @param theElement [in] the element to check. + //! @return True if element can be rendered. + virtual Standard_Boolean CanRender (const OpenGl_Element* theElement); + +public: + + DEFINE_STANDARD_RTTI(OpenGl_CappingAlgoFilter) +}; + +#endif diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.cxx b/src/OpenGl/OpenGl_CappingPlaneResource.cxx new file mode 100644 index 0000000000..b7009c2c29 --- /dev/null +++ b/src/OpenGl/OpenGl_CappingPlaneResource.cxx @@ -0,0 +1,171 @@ +// Created on: 2013-08-15 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource, OpenGl_Resource) + +// ======================================================================= +// function : OpenGl_CappingPlaneResource +// purpose : +// ======================================================================= +OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane) +: myOrientation (OpenGl_IdentityMatrix), + myAspect (NULL), + myPlaneRoot (thePlane), + myEquationMod (0), + myAspectMod (0) +{} + +// ======================================================================= +// function : OpenGl_CappingPlaneResource +// purpose : +// ======================================================================= +OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource() +{ + Release (NULL); +} + +// ======================================================================= +// function : Update +// purpose : +// ======================================================================= +void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext) +{ + UpdateTransform(); + UpdateAspect (theContext); +} + +// ======================================================================= +// function : Release +// purpose : +// ======================================================================= +void OpenGl_CappingPlaneResource::Release (const OpenGl_Context* theContext) +{ + OpenGl_Element::Destroy (theContext, myAspect); + myEquationMod = 0; + myAspectMod = 0; +} + +// ======================================================================= +// function : UpdateAspect +// purpose : +// ======================================================================= +void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext) +{ + Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect(); + if (myAspect != NULL && !aCappingAsp.IsNull()) + { + if (myAspectMod == myPlaneRoot->MCountAspect()) + return; // noting to update + + myAspect->Init (theContext, aCappingAsp); + myAspectMod = myPlaneRoot->MCountAspect(); + return; + } + + // no more used + if (myAspect != NULL && aCappingAsp.IsNull()) + { + OpenGl_Element::Destroy (theContext, myAspect); + myAspectMod = myPlaneRoot->MCountAspect(); + return; + } + + // first created + if (myAspect == NULL && !aCappingAsp.IsNull()) + { + myAspect = new OpenGl_AspectFace(); + myAspect->Init (theContext, aCappingAsp); + myAspectMod = myPlaneRoot->MCountAspect(); + } +} + +// ======================================================================= +// function : UpdateTransform +// purpose : +// ======================================================================= +void OpenGl_CappingPlaneResource::UpdateTransform() +{ + const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation(); + if (myEquationMod == myPlaneRoot->MCountEquation()) + { + return; // nothing to update + } + + // re-evaluate infinite plane transformation matrix + Standard_ShortReal N[3] = + { (Standard_ShortReal)anEquation[0], + (Standard_ShortReal)anEquation[1], + (Standard_ShortReal)anEquation[2] }; + + Standard_ShortReal T[3] = + { (Standard_ShortReal)(anEquation[0] * -anEquation[3]), + (Standard_ShortReal)(anEquation[1] * -anEquation[3]), + (Standard_ShortReal)(anEquation[2] * -anEquation[3]) }; + + Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f }; + Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f }; + + // project plane normal onto OX to find left vector + Standard_ShortReal aConfusion = (Standard_ShortReal)Precision::Confusion(); + Standard_ShortReal aProjLen = + sqrt ( (Standard_ShortReal)(anEquation[0] * anEquation[0]) + + (Standard_ShortReal)(anEquation[2] * anEquation[2])); + if (aProjLen < aConfusion) + { + L[0] = 1.0f; + } + else + { + L[0] = N[2] / aProjLen; + L[2] = -N[0] / aProjLen; + } + + // (-aLeft) x aNorm + F[0] = (-L[1])*N[2] - (-L[2])*N[1]; + F[1] = (-L[2])*N[0] - (-L[0])*N[2]; + F[2] = (-L[0])*N[1] - (-L[1])*N[0]; + + myOrientation.mat[0][0] = L[0]; + myOrientation.mat[0][1] = L[1]; + myOrientation.mat[0][2] = L[2]; + myOrientation.mat[0][3] = 0.0f; + + myOrientation.mat[1][0] = N[0]; + myOrientation.mat[1][1] = N[1]; + myOrientation.mat[1][2] = N[2]; + myOrientation.mat[1][3] = 0.0f; + + myOrientation.mat[2][0] = F[0]; + myOrientation.mat[2][1] = F[1]; + myOrientation.mat[2][2] = F[2]; + myOrientation.mat[2][3] = 0.0f; + + myOrientation.mat[3][0] = T[0]; + myOrientation.mat[3][1] = T[1]; + myOrientation.mat[3][2] = T[2]; + myOrientation.mat[3][3] = 1.0f; + + myEquationMod = myPlaneRoot->MCountEquation(); +} diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.hxx b/src/OpenGl/OpenGl_CappingPlaneResource.hxx new file mode 100644 index 0000000000..b66c03937f --- /dev/null +++ b/src/OpenGl/OpenGl_CappingPlaneResource.hxx @@ -0,0 +1,88 @@ +// Created on: 2013-08-15 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _OpenGl_CappingPlaneResource_H__ +#define _OpenGl_CappingPlaneResource_H__ + +#include +#include +#include +#include + +class Handle(OpenGl_Context); + +DEFINE_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource) + +//! Container of graphical resources for rendering capping plane +//! associated to graphical clipping plane. +//! This resource holds data necessary for OpenGl_CappingAlgo. +//! This object is implemented as OpenGl resource for the following reasons: +//! - one instance should be shared between contexts. +//! - instance associated to Graphic3d_ClipPlane data by id. +//! - should created and released within context (owns OpenGl elements and resources). +class OpenGl_CappingPlaneResource : public OpenGl_Resource +{ +public: + + //! Constructor. + //! Create capping plane presentation associated to clipping plane data. + //! @param thePlane [in] the plane data. + Standard_EXPORT OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane); + + //! Destroy object. + Standard_EXPORT virtual ~OpenGl_CappingPlaneResource(); + + //! Update resource data in the passed context. + //! @param theContext [in] the context. + Standard_EXPORT void Update (const Handle(OpenGl_Context)& theContext); + + //! Release associated OpenGl resources. + //! @param theContext [in] the resource context. + Standard_EXPORT void Release (const OpenGl_Context* theContext); + + //! @return aspect face for rendering capping surface. + inline const OpenGl_AspectFace* AspectFace() const { return myAspect; } + + //! @return evaluated orientation matrix to transform infinite plane. + inline const OpenGl_Matrix* Orientation() const { return &myOrientation; } + +private: + + //! Update precomputed plane orientation matrix. + void UpdateTransform(); + + //! Update resources. + //! @param theContext [in] the context. + void UpdateAspect (const Handle(OpenGl_Context)& theContext); + +private: + + OpenGl_Matrix myOrientation; //!< plane transformation matrix. + OpenGl_AspectFace* myAspect; //!< capping face aspect. + Handle(Graphic3d_ClipPlane) myPlaneRoot; //!< parent clipping plane structure. + unsigned int myEquationMod; //!< modification counter for plane equation. + unsigned int myAspectMod; //!< modification counter for aspect. + +public: + + DEFINE_STANDARD_RTTI(OpenGl_CappingPlaneResource) // Type definition + +}; + +#endif diff --git a/src/OpenGl/OpenGl_ClippingState.cxx b/src/OpenGl/OpenGl_ClippingState.cxx new file mode 100644 index 0000000000..308adbab8a --- /dev/null +++ b/src/OpenGl/OpenGl_ClippingState.cxx @@ -0,0 +1,248 @@ +// Created on: 2013-09-05 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#include +#include + +namespace +{ + static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0}; +}; + +// ======================================================================= +// function : OpenGl_ClippingState +// purpose : +// ======================================================================= +OpenGl_ClippingState::OpenGl_ClippingState () +: myPlanes(), + myPlaneStates(), + myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5)) +{} + +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +void OpenGl_ClippingState::Init (const Standard_Integer theMaxPlanes) +{ + myPlanes.Clear(); + myPlaneStates.Clear(); + Standard_Integer aLowerId = GL_CLIP_PLANE0; + Standard_Integer aUpperId = GL_CLIP_PLANE0 + theMaxPlanes - 1; + myEmptyPlaneIds = new Aspect_GenId (aLowerId, aUpperId); +} + +// ======================================================================= +// function : Planes +// purpose : +// ======================================================================= +Graphic3d_SetOfHClipPlane OpenGl_ClippingState::Planes() const +{ + Graphic3d_SetOfHClipPlane aRes; + OpenGl_MapOfContextPlanes::Iterator anIt (myPlanes); + for (; anIt.More(); anIt.Next()) + { + aRes.Add (anIt.Key()); + } + + return aRes; +} + +// ======================================================================= +// function : IsSet +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_ClippingState::IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const +{ + return myPlanes.IsBound (thePlane); +} + +// ======================================================================= +// function : Set +// purpose : +// ======================================================================= +void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes, + const Standard_Boolean theToEnable) +{ + Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes); + for (; aPlaneIt.More() && myEmptyPlaneIds->Available() > 0; aPlaneIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); + if (IsSet (aPlane)) + return; + + Standard_Integer anId = myEmptyPlaneIds->Next(); + myPlanes.Bind (aPlane, anId); + myPlaneStates.Bind (aPlane, theToEnable); + + const GLenum anOpenGlId = (GLenum)anId; + if (theToEnable) + { + glEnable (anOpenGlId); + } + else + { + glDisable (anOpenGlId); + } + + glClipPlane (anOpenGlId, aPlane->GetEquation()); + } +} + +// ======================================================================= +// function : Set +// purpose : +// ======================================================================= +void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes, + const OpenGl_Matrix* theViewMatrix, + const Standard_Boolean theToEnable) +{ + GLint aMatrixMode; + glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); + + OpenGl_Matrix aCurrentMat; + glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*)aCurrentMat.mat); + + if (aMatrixMode != GL_MODELVIEW) + { + glMatrixMode (GL_MODELVIEW); + } + + // load equation transform matrices + glLoadMatrixf ((theViewMatrix != NULL) + ? (const GLfloat*)theViewMatrix->mat + : (const GLfloat*)OpenGl_IdentityMatrix.mat); + + Set (thePlanes, theToEnable); + + // restore model-view matrix + glLoadMatrixf ((GLfloat*)aCurrentMat.mat); + + // restore context matrix state + if (aMatrixMode != GL_MODELVIEW) + { + glMatrixMode (aMatrixMode); + } +} + +// ======================================================================= +// function : Unset +// purpose : +// ======================================================================= +void OpenGl_ClippingState::Unset (const Graphic3d_SetOfHClipPlane& thePlanes) +{ + Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes); + for (; aPlaneIt.More(); aPlaneIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); + if (!IsSet (aPlane)) + continue; + + Standard_Integer anId = myPlanes.Find (aPlane); + myEmptyPlaneIds->Free (anId); + myPlanes.UnBind (aPlane); + myPlaneStates.UnBind (aPlane); + + const GLenum anOpenGlId = (GLenum)anId; + + glDisable (anOpenGlId); + glClipPlane (anOpenGlId, OpenGl_DefaultPlaneEq); + } +} + +// +//// ======================================================================= +//// function : SetPlane +//// purpose : +//// ======================================================================= +//Standard_Boolean OpenGl_ClippingState::SetPlane (const Handle(Graphic3d_ClipPlane)& thePlane, +// const Standard_Boolean theToEnable) +//{ +// if (myEmptyPlaneIds->Available() == 0) +// return Standard_False; +// +// if (IsPlaneSet (thePlane)) +// return Standard_True; +// +// Standard_Integer aPlaneId = myEmptyPlaneIds->Next(); +// myPlanes.Bind (thePlane, aPlaneId); +// myPlaneStates.Bind (thePlane, theToEnable); +// if (theToEnable) +// glEnable (aPlaneId); +// else +// glDisable (aPlaneId); +// +// glClipPlane (aPlaneId, thePlane->GetEquation()); +// +// return Standard_True; +//} + +//// ======================================================================= +//// function : UnsetPlane +//// purpose : +//// ======================================================================= +//void OpenGl_ClippingState::UnsetPlane (const Handle(Graphic3d_ClipPlane)& thePlane) +//{ +// if (!IsPlaneSet (thePlane)) +// return; +// +// Standard_Integer aPlaneId = myPlanes.Find (thePlane); +// +// myEmptyPlaneIds->Free (aPlaneId); +// myPlanes.UnBind (thePlane); +// myPlaneStates.UnBind (thePlane); +// +// glDisable (aPlaneId); +// glClipPlane (aPlaneId, OpenGl_DefaultPlaneEq); +//} + +// ======================================================================= +// function : IsEnabled +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_ClippingState::IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const +{ + Standard_Boolean isSet; + return IsSet (thePlane) + && myPlaneStates.Find (thePlane, isSet) + && isSet; +} + +// ======================================================================= +// function : SetEnabled +// purpose : +// ======================================================================= +void OpenGl_ClippingState::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane, + const Standard_Boolean theIsEnabled) +{ + if (!IsSet (thePlane)) + return; + + Standard_Boolean& aState = myPlaneStates.ChangeFind (thePlane); + if (theIsEnabled == aState) + return; + + Standard_Integer aPlaneId = myPlanes.Find (thePlane); + if (theIsEnabled) + glEnable (aPlaneId); + else + glDisable (aPlaneId); + + aState = theIsEnabled; +} diff --git a/src/OpenGl/OpenGl_ClippingState.hxx b/src/OpenGl/OpenGl_ClippingState.hxx new file mode 100644 index 0000000000..c52df31782 --- /dev/null +++ b/src/OpenGl/OpenGl_ClippingState.hxx @@ -0,0 +1,103 @@ +// Created on: 2013-09-05 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _OpenGl_ClippingState_H__ +#define _OpenGl_ClippingState_H__ + +#include +#include +#include +#include +#include +#include +#include + +//! This class contains logics related to tracking and modification of clipping plane +//! state for particular OpenGl context. It contains information about enabled +//! clipping planes and provides method to change clippings in context. The methods +//! should be executed within OpenGl context associated with instance of this +//! class. +class OpenGl_ClippingState +{ +public: + + //! Default constructor. + Standard_EXPORT OpenGl_ClippingState (); + + //! Initialize. + //! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context. + Standard_EXPORT void Init (const Standard_Integer theMaxPlanes); + + //! @return sequence of set clipping planes. + Standard_EXPORT Graphic3d_SetOfHClipPlane Planes() const; + + //! Check whether the clipping plane has been set for the current context state. + //! @param thePlane [in] the plane to check. + //! @return True if plane is set. + Standard_EXPORT Standard_Boolean IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const; + + //! Set collection of clipping planes for available plane ids. Current model view matrix is used. + //! @param thePlanes [in] collection of planes. + //! @param theToEnable [in] the boolean flag notifying whether the planes should be enabled. + Standard_EXPORT void Set (const Graphic3d_SetOfHClipPlane& thePlanes, + const Standard_Boolean theToEnable = Standard_True); + + //! Set collection of clipping planes for available plane ids. Identity matrix in case + //! if passed matrix pointer is NULL. + //! @param thePlanes [in] collection of planes. + //! @param theViewMatrix [in] view matrix to be used to define plane equation. + //! @param theToEnable [in] the boolean flag notifying whether the planes should be enabled. + Standard_EXPORT void Set (const Graphic3d_SetOfHClipPlane& thePlanes, + const OpenGl_Matrix* theViewMatrix, + const Standard_Boolean theToEnable = Standard_True); + + //! Unset and disable collection of clipping planes. + //! @param thePlanes [in] the plane to deactivate. + Standard_EXPORT void Unset (const Graphic3d_SetOfHClipPlane& thePlanes); + + //! Check whether the clipping plane has been set and enabled for the current context state. + //! @param thePlane [in] the plane to check. + //! @return True if plane is enabled. + Standard_EXPORT Standard_Boolean IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const; + + //! Change enabled / disabled state of the clipping plane. + //! @param thePlane [in] the plane to change the state. + //! @param theIsEnabled [in] the flag indicating whether the plane should be enabled or not. + //! @return False if plane is not set for the context. + Standard_EXPORT void SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane, const Standard_Boolean theIsEnabled); + +private: + + typedef NCollection_DataMap OpenGl_MapOfContextPlanes; + typedef NCollection_DataMap OpenGl_MapOfPlaneStates; + typedef NCollection_Handle OpenGl_EmptyPlaneIds; + + OpenGl_MapOfContextPlanes myPlanes; //!< map of clip planes bound for the ids + OpenGl_MapOfPlaneStates myPlaneStates; //!< map of clip planes state (enabled/disabled). + OpenGl_EmptyPlaneIds myEmptyPlaneIds; //!< generator of empty ids + +private: + + //! Copying allowed only within Handles + OpenGl_ClippingState (const OpenGl_ClippingState& ); + OpenGl_ClippingState& operator= (const OpenGl_ClippingState& ); + +}; + +#endif diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 09cd4a562a..765f9bc839 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -64,6 +64,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient) namespace { static const Handle(OpenGl_Resource) NULL_GL_RESOURCE; + static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0}; }; // ======================================================================= @@ -91,10 +92,12 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) mySharedResources (new OpenGl_ResourcesMap()), myDelayed (new OpenGl_DelayReleaseMap()), myReleaseQueue (new OpenGl_ResourcesQueue()), + myClippingState (), myGlLibHandle (NULL), myGlCore20 (NULL), - myAnisoMax (1), myMaxTexDim (1024), + myMaxClipPlanes (6), + myAnisoMax (1), myGlVerMajor (0), myGlVerMinor (0), myIsFeedback (Standard_False), @@ -162,6 +165,15 @@ Standard_Integer OpenGl_Context::MaxTextureSize() const return myMaxTexDim; } +// ======================================================================= +// function : MaxClipPlanes +// purpose : +// ======================================================================= +Standard_Integer OpenGl_Context::MaxClipPlanes() const +{ + return myMaxClipPlanes; +} + // ======================================================================= // function : Share // purpose : @@ -594,12 +606,16 @@ void OpenGl_Context::init() atiMem = CheckExtension ("GL_ATI_meminfo"); nvxMem = CheckExtension ("GL_NVX_gpu_memory_info"); + // get number of maximum clipping planes + glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes); glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim); if (extAnis) { glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax); } + myClippingState.Init (myMaxClipPlanes); + // initialize debug context extension if (CheckExtension ("GL_ARB_debug_output")) { diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index ecdc69c8e9..52fc99907f 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include //! Forward declarations struct OpenGl_GlCore12; @@ -238,12 +240,26 @@ public: //! Clean up the delayed release queue. Standard_EXPORT void ReleaseDelayed(); + //! @return tool for management of clippings within this context. + inline OpenGl_ClippingState& ChangeClipping() { return myClippingState; } + + //! @return tool for management of clippings within this context. + inline const OpenGl_ClippingState& Clipping() const { return myClippingState; } + +public: + //! @return maximum degree of anisotropy texture filter Standard_EXPORT Standard_Integer MaxDegreeOfAnisotropy() const; //! @return value for GL_MAX_TEXTURE_SIZE Standard_EXPORT Standard_Integer MaxTextureSize() const; + //! Get maximum number of clip planes supported by OpenGl. + //! This value is implementation dependant. At least 6 + //! planes should be supported by OpenGl (see specs). + //! @return value for GL_MAX_CLIP_PLANES + Standard_EXPORT Standard_Integer MaxClipPlanes() const; + private: //! Wrapper to system function to retrieve GL function pointer by name. @@ -306,15 +322,19 @@ private: // context info Handle(OpenGl_DelayReleaseMap) myDelayed; //!< shared resources for delayed release Handle(OpenGl_ResourcesQueue) myReleaseQueue; //!< queue of resources for delayed clean up + OpenGl_ClippingState myClippingState; //!< state of clip planes + void* myGlLibHandle; //!< optional handle to GL library OpenGl_GlCore20* myGlCore20; //!< common structure for GL core functions upto 2.0 Standard_Integer myAnisoMax; //!< maximum level of anisotropy texture filter Standard_Integer myMaxTexDim; //!< value for GL_MAX_TEXTURE_SIZE + Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES Standard_Integer myGlVerMajor; //!< cached GL version major number Standard_Integer myGlVerMinor; //!< cached GL version minor number Standard_Boolean myIsFeedback; //!< flag indicates GL_FEEDBACK mode Standard_Boolean myIsInitialized; //!< flag indicates initialization state + private: //! Copying allowed only within Handles diff --git a/src/OpenGl/OpenGl_Element.hxx b/src/OpenGl/OpenGl_Element.hxx index b900f28132..44fa1dc200 100644 --- a/src/OpenGl/OpenGl_Element.hxx +++ b/src/OpenGl/OpenGl_Element.hxx @@ -22,6 +22,7 @@ #include #include +#include //! Base interface for drawable elements. class OpenGl_Element @@ -50,6 +51,30 @@ public: theElement = NULL; } +public: + + //! Render element if it passes the filtering procedure. This method should + //! be used for elements which can be used in scope of rendering algorithms. + //! E.g. elements of groups during recursive rendering. + //! If render filter is null, pure rendering is performed. + //! @param theWorkspace [in] the rendering workspace. + //! @param theFilter [in] the rendering filter to check whether the element + //! should be rendered or not. + //! @return True if element passes the filering check and is rendered. + inline Standard_Boolean + RenderFiltered (const Handle(OpenGl_Workspace)& theWorkspace, + const Handle(OpenGl_RenderFilter)& theFilter) const + { + if (!theFilter.IsNull() && !theFilter->CanRender (this)) + { + return Standard_False; + } + + Render (theWorkspace); + + return Standard_True; + } + protected: Standard_EXPORT virtual ~OpenGl_Element(); diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index a3ae77f695..f2f86c9580 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -152,7 +152,8 @@ public: Standard_EXPORT void Redraw (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer, const Standard_Integer x = 0, const Standard_Integer y = 0, const Standard_Integer width = 0, const Standard_Integer height = 0); Standard_EXPORT void RemoveView (const Graphic3d_CView& ACView); Standard_EXPORT void SetLight (const Graphic3d_CView& ACView); - Standard_EXPORT void SetPlane (const Graphic3d_CView& ACView); + Standard_EXPORT void SetClipPlanes (const Graphic3d_CView& theCView); + Standard_EXPORT void SetClipPlanes (const Graphic3d_CStructure& theCStructure); Standard_EXPORT void SetVisualisation (const Graphic3d_CView& ACView); Standard_EXPORT void TransformStructure (const Graphic3d_CStructure& ACStructure); Standard_EXPORT void Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag); diff --git a/src/OpenGl/OpenGl_GraphicDriver_7.cxx b/src/OpenGl/OpenGl_GraphicDriver_7.cxx index 4e91e47723..5b183776a4 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_7.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_7.cxx @@ -448,11 +448,22 @@ void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView) aCView->View->SetLights(ACView.Context); } -void OpenGl_GraphicDriver::SetPlane (const Graphic3d_CView& ACView) +void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CView& theCView) { - const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView; + const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView; if (aCView) - aCView->View->SetClippingPlanes(ACView.Context); + { + aCView->View->SetClipPlanes (theCView.Context.ClipPlanes); + } +} + +void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CStructure& theCStructure) +{ + OpenGl_Structure* aStructure = (OpenGl_Structure *)theCStructure.ptrStructure; + if (aStructure) + { + aStructure->SetClipPlanes (theCStructure.ClipPlanes); + } } void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView) diff --git a/src/OpenGl/OpenGl_Group.cxx b/src/OpenGl/OpenGl_Group.cxx index b6f81ad0c9..a6471518b2 100644 --- a/src/OpenGl/OpenGl_Group.cxx +++ b/src/OpenGl/OpenGl_Group.cxx @@ -22,8 +22,10 @@ #include #include -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : OpenGl_Group +// purpose : +// ======================================================================= OpenGl_Group::OpenGl_Group () : myAspectLine(NULL), myAspectFace(NULL), @@ -33,13 +35,19 @@ OpenGl_Group::OpenGl_Group () { } +// ======================================================================= +// function : ~OpenGl_Group +// purpose : +// ======================================================================= OpenGl_Group::~OpenGl_Group() { Release (Handle(OpenGl_Context)()); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectLine +// purpose : +// ======================================================================= void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext, const Standard_Boolean theIsGlobal) { @@ -57,8 +65,10 @@ void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext, } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectFace +// purpose : +// ======================================================================= void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)& theCtx, const CALL_DEF_CONTEXTFILLAREA& theAspect, const Standard_Boolean theIsGlobal) @@ -79,8 +89,10 @@ void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)& theCtx, } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectMarker +// purpose : +// ======================================================================= void OpenGl_Group::SetAspectMarker (const Handle(OpenGl_Context)& theCtx, const CALL_DEF_CONTEXTMARKER& theAspect, const Standard_Boolean theIsGlobal) @@ -101,8 +113,10 @@ void OpenGl_Group::SetAspectMarker (const Handle(OpenGl_Context)& theCtx, } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectText +// purpose : +// ======================================================================= void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext, const Standard_Boolean theIsGlobal) { @@ -120,8 +134,10 @@ void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext, } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : AddElement +// purpose : +// ======================================================================= void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem ) { OpenGl_ElementNode *node = new OpenGl_ElementNode(); @@ -133,34 +149,25 @@ void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem ) myLast = node; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : Render +// purpose : +// ======================================================================= void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const { // Is rendering in ADD or IMMEDIATE mode? const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0; + const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter(); // Setup aspects const OpenGl_AspectLine* aBackAspectLine = theWorkspace->AspectLine (Standard_False); const OpenGl_AspectFace* aBackAspectFace = theWorkspace->AspectFace (Standard_False); const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False); const OpenGl_AspectText* aBackAspectText = theWorkspace->AspectText (Standard_False); - if (myAspectLine) - { - theWorkspace->SetAspectLine (myAspectLine); - } - if (myAspectFace) - { - theWorkspace->SetAspectFace (myAspectFace); - } - if (myAspectMarker) - { - theWorkspace->SetAspectMarker (myAspectMarker); - } - if (myAspectText) - { - theWorkspace->SetAspectText (myAspectText); - } + Standard_Boolean isLineSet = myAspectLine && myAspectLine->RenderFiltered (theWorkspace, aFilter); + Standard_Boolean isFaceSet = myAspectFace && myAspectFace->RenderFiltered (theWorkspace, aFilter); + Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter); + Standard_Boolean isTextSet = myAspectText && myAspectText->RenderFiltered (theWorkspace, aFilter); // Render group elements for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next) @@ -177,24 +184,32 @@ void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const glDepthMask (GL_FALSE); } - aNodeIter->elem->Render (theWorkspace); + aNodeIter->elem->RenderFiltered (theWorkspace, aFilter); break; } default: { - aNodeIter->elem->Render (theWorkspace); + aNodeIter->elem->RenderFiltered (theWorkspace, aFilter); break; } } } // Restore aspects - theWorkspace->SetAspectLine (aBackAspectLine); - theWorkspace->SetAspectFace (aBackAspectFace); - theWorkspace->SetAspectMarker (aBackAspectMarker); - theWorkspace->SetAspectText (aBackAspectText); + if (isLineSet) + theWorkspace->SetAspectLine (aBackAspectLine); + if (isFaceSet) + theWorkspace->SetAspectFace (aBackAspectFace); + if (isMarkerSet) + theWorkspace->SetAspectMarker (aBackAspectMarker); + if (isTextSet) + theWorkspace->SetAspectText (aBackAspectText); } +// ======================================================================= +// function : Release +// purpose : +// ======================================================================= void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx) { // Delete elements diff --git a/src/OpenGl/OpenGl_Group.hxx b/src/OpenGl/OpenGl_Group.hxx index 4d4d9c77a2..47ca2da4e8 100644 --- a/src/OpenGl/OpenGl_Group.hxx +++ b/src/OpenGl/OpenGl_Group.hxx @@ -20,6 +20,7 @@ #ifndef _OpenGl_Group_Header #define _OpenGl_Group_Header +#include #include #include @@ -31,6 +32,10 @@ #include +class OpenGl_Group; + +typedef NCollection_List OpenGl_ListOfGroup; + struct OpenGl_ElementNode { TelType type; diff --git a/src/OpenGl/OpenGl_Matrix.hxx b/src/OpenGl/OpenGl_Matrix.hxx index 85dec0511b..cf9f875b09 100644 --- a/src/OpenGl/OpenGl_Matrix.hxx +++ b/src/OpenGl/OpenGl_Matrix.hxx @@ -32,4 +32,13 @@ struct OpenGl_Matrix Standard_EXPORT void OpenGl_Multiplymat3 (OpenGl_Matrix *c, const OpenGl_Matrix *a, const OpenGl_Matrix *b); Standard_EXPORT void OpenGl_Transposemat3 (OpenGl_Matrix *c, const OpenGl_Matrix *a); +const static OpenGl_Matrix OpenGl_IdentityMatrix = +{ + // mat[4][4] + { { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f } } +}; + #endif //OpenGl_Matrix_Header diff --git a/src/Graphic3d/Graphic3d_CPlane.cxx b/src/OpenGl/OpenGl_RenderFilter.cxx old mode 100755 new mode 100644 similarity index 77% rename from src/Graphic3d/Graphic3d_CPlane.cxx rename to src/OpenGl/OpenGl_RenderFilter.cxx index f1c1e6b312..2b79cb5019 --- a/src/Graphic3d/Graphic3d_CPlane.cxx +++ b/src/OpenGl/OpenGl_RenderFilter.cxx @@ -1,4 +1,6 @@ -// Copyright (c) 1999-2012 OPEN CASCADE SAS +// Created on: 2013-07-25 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file @@ -15,12 +17,7 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. +#include -#include - -const Handle(Standard_Type)& TYPE(Graphic3d_CPlane) -{ - static Handle(Standard_Type) _atype = - new Standard_Type ("Graphic3d_CPlane", sizeof (Graphic3d_CPlane)); - return _atype; -} +IMPLEMENT_STANDARD_HANDLE(OpenGl_RenderFilter, Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RenderFilter, Standard_Transient) diff --git a/src/OpenGl/OpenGl_RenderFilter.hxx b/src/OpenGl/OpenGl_RenderFilter.hxx new file mode 100644 index 0000000000..196fe69232 --- /dev/null +++ b/src/OpenGl/OpenGl_RenderFilter.hxx @@ -0,0 +1,47 @@ +// Created on: 2013-07-25 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _OpenGl_RenderFilter_H__ +#define _OpenGl_RenderFilter_H__ + +#include +#include + +DEFINE_STANDARD_HANDLE (OpenGl_RenderFilter, Standard_Transient) + +class OpenGl_Element; + +//! Base class for defining element rendering filters. +//! This class can be used in pair with advance rendering passes, and for +//! disabling rendering (setting up) graphical aspects. +class OpenGl_RenderFilter : public Standard_Transient +{ +public: + + //! Checks whether the element can be rendered or not. + //! @param theElement [in] the element to check. + //! @return True if element can be rendered. + virtual Standard_Boolean CanRender (const OpenGl_Element* theElement) = 0; + +public: + + DEFINE_STANDARD_RTTI(OpenGl_RenderFilter) +}; + +#endif diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index 47a436e475..16a9ff9845 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -24,7 +24,8 @@ #include #include #include - +#include +#include #include //! Auxiliary class for bounding box presentation @@ -111,6 +112,10 @@ public: /*----------------------------------------------------------------------*/ +// ======================================================================= +// function : call_util_transpose_mat +// purpose : +// ======================================================================= static void call_util_transpose_mat (float tmat[16], float mat[4][4]) { int i, j; @@ -120,8 +125,10 @@ static void call_util_transpose_mat (float tmat[16], float mat[4][4]) tmat[j*4+i] = mat[i][j]; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : OpenGl_Structure +// purpose : +// ======================================================================= OpenGl_Structure::OpenGl_Structure () : myTransformation(NULL), myTransPers(NULL), @@ -136,8 +143,10 @@ OpenGl_Structure::OpenGl_Structure () { } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : ~OpenGl_Structure +// purpose : +// ======================================================================= OpenGl_Structure::~OpenGl_Structure() { Release (Handle(OpenGl_Context)()); @@ -145,8 +154,10 @@ OpenGl_Structure::~OpenGl_Structure() delete myTransPers; myTransPers = NULL; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetTransformation +// purpose : +// ======================================================================= void OpenGl_Structure::SetTransformation(const float *AMatrix) { if (!myTransformation) @@ -155,8 +166,10 @@ void OpenGl_Structure::SetTransformation(const float *AMatrix) matcpy( myTransformation->mat, AMatrix ); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetTransformPersistence +// purpose : +// ======================================================================= void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers) { if (!myTransPers) @@ -168,8 +181,10 @@ void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTE myTransPers->pointZ = ATransPers.Point.z; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectLine +// purpose : +// ======================================================================= void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext) { if (!myAspectLine) @@ -177,8 +192,10 @@ void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext) myAspectLine->SetContext( AContext ); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectFace +// purpose : +// ======================================================================= void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)& theCtx, const CALL_DEF_CONTEXTFILLAREA& theAspect) { @@ -189,8 +206,10 @@ void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)& theCtx, myAspectFace->Init (theCtx, theAspect); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectMarker +// purpose : +// ======================================================================= void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx, const CALL_DEF_CONTEXTMARKER& theAspect) { @@ -201,8 +220,10 @@ void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx, myAspectMarker->Init (theCtx, theAspect); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetAspectText +// purpose : +// ======================================================================= void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext) { if (!myAspectText) @@ -210,8 +231,10 @@ void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext) myAspectText->SetContext( AContext ); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetHighlightBox +// purpose : +// ======================================================================= void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx, const CALL_DEF_BOUNDBOX& theBoundBox) { @@ -234,8 +257,10 @@ void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx, myHighlightBox->AddElement (TelParray, aBndBoxPrs); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : ClearHighlightBox +// purpose : +// ======================================================================= void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx) { if (myHighlightBox != NULL) @@ -244,8 +269,10 @@ void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : SetHighlightColor +// purpose : +// ======================================================================= void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx, const Standard_ShortReal R, const Standard_ShortReal G, @@ -263,8 +290,10 @@ void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx myHighlightColor->rgb[3] = 1.F; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : ClearHighlightColor +// purpose : +// ======================================================================= void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx) { ClearHighlightBox(theGlCtx); @@ -272,16 +301,20 @@ void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlC myHighlightColor = NULL; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : Connect +// purpose : +// ======================================================================= void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure) { Disconnect (AStructure); myConnected.Append(AStructure); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : Disconnect +// purpose : +// ======================================================================= void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure) { OpenGl_ListOfStructure::Iterator its(myConnected); @@ -297,8 +330,10 @@ void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure) } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : AddGroup +// purpose : +// ======================================================================= OpenGl_Group * OpenGl_Structure::AddGroup () { // Create new group @@ -307,8 +342,10 @@ OpenGl_Group * OpenGl_Structure::AddGroup () return g; } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : RemoveGroup +// purpose : +// ======================================================================= void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx, const OpenGl_Group* theGroup) { @@ -325,8 +362,10 @@ void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx, } } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx) { // Release groups @@ -338,8 +377,10 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx) myGroups.Clear(); } -/*----------------------------------------------------------------------*/ - +// ======================================================================= +// function : Render +// purpose : +// ======================================================================= void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const { // Process the structure only if visible @@ -415,6 +456,25 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const its.Next(); } + // Set up plane equations for non-structure transformed global model-view matrix + const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext(); + + // Collect planes which should be turned on for structure + Graphic3d_SetOfHClipPlane aPlanesOn; + Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes); + for (; aPlaneIt.More(); aPlaneIt.Next()) + { + const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value(); + if (aUserPln->IsOn()) + aPlanesOn.Add (aUserPln); + } + + // set structure clipping planes + if (aPlanesOn.Size() > 0) + { + aContext->ChangeClipping().Set (aPlanesOn, AWorkspace->ViewMatrix()); + } + // Render groups OpenGl_ListOfGroup::Iterator itg(myGroups); while (itg.More()) @@ -423,6 +483,15 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const itg.Next(); } + // Render cappings for structure groups + OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups); + + // unset structure clipping planes + if (aPlanesOn.Size() > 0) + { + aContext->ChangeClipping().Unset (aPlanesOn); + } + // Restore highlight color AWorkspace->HighlightColor = highlight_color; @@ -514,7 +583,6 @@ void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCt //function : SetZLayer //purpose : //======================================================================= - void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex) { myZLayer = theLayerIndex; @@ -524,7 +592,6 @@ void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex) //function : GetZLayer //purpose : //======================================================================= - Standard_Integer OpenGl_Structure::GetZLayer () const { return myZLayer; diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index 978ace2fc1..e4c4b55c5d 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -31,10 +31,11 @@ #include #include +#include + class OpenGl_Structure; typedef NCollection_List OpenGl_ListOfStructure; -typedef NCollection_List OpenGl_ListOfGroup; class OpenGl_Structure : public OpenGl_Element { @@ -68,6 +69,8 @@ public: void SetNamedStatus (const Standard_Integer aStatus) { myNamedStatus = aStatus; } + void SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; } + void Connect (const OpenGl_Structure *astructure); void Disconnect (const OpenGl_Structure *astructure); @@ -97,6 +100,11 @@ protected: virtual ~OpenGl_Structure(); + //! Draw capping surfaces by h/w for the clipping planes + //! enabled for the structure. + //! @param theWorkspace [in] the GL workspace, context state. + void DrawCapping (const Handle(OpenGl_Workspace)& theWorkspace) const; + protected: //Structure_LABBegin @@ -116,6 +124,7 @@ protected: OpenGl_ListOfStructure myConnected; OpenGl_ListOfGroup myGroups; + Graphic3d_SetOfHClipPlane myClipPlanes; public: diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index d181b751c9..b9fff66b74 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -245,30 +245,6 @@ void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext) /*----------------------------------------------------------------------*/ -//call_togl_setplane -void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext) -{ - // clear clipping planes information - myClippingPlanes.Clear(); - // update information - int i = 0; - for (; i < AContext.NbActivePlane; i++) - { - const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i]; - if ( aCPlane.Active && aCPlane.PlaneId > 0 ) - { - OPENGL_CLIP_REP aPlane; - aPlane.equation[0] = aCPlane.CoefA; - aPlane.equation[1] = aCPlane.CoefB; - aPlane.equation[2] = aCPlane.CoefC; - aPlane.equation[3] = aCPlane.CoefD; - myClippingPlanes.Append( aPlane ); - } - } -} - -/*----------------------------------------------------------------------*/ - //call_togl_setvisualisation void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext) { diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 9598f65ce7..15593c7bb8 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -72,12 +73,6 @@ struct OPENGL_EXTRA_REP Tfloat scaleFactors[3]; }; -struct OPENGL_CLIP_REP -{ - Standard_Real equation[4]; - DEFINE_STANDARD_ALLOC -}; - struct OPENGL_ZCLIP { struct { @@ -117,7 +112,7 @@ class OpenGl_View : public MMgt_TShared void SetBackfacing (const Standard_Integer AMode); void SetLights (const CALL_DEF_VIEWCONTEXT &AContext); void SetAntiAliasing (const Standard_Boolean AMode) { myAntiAliasing = AMode; } - void SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext); + void SetClipPlanes (const Graphic3d_SetOfHClipPlane &thePlanes) { myClipPlanes = thePlanes; } void SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext); void SetClipLimit (const Graphic3d_CView& theCView); @@ -222,11 +217,11 @@ public: //Tint active_status; OPENGL_ZCLIP myZClip; - NCollection_List myClippingPlanes; - OPENGL_EXTRA_REP myExtra; //} + Graphic3d_SetOfHClipPlane myClipPlanes; + OPENGL_FOG myFog; OpenGl_Trihedron* myTrihedron; OpenGl_GraduatedTrihedron* myGraduatedTrihedron; diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index a9faf4627f..5a054c3674 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -638,10 +638,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, const Aspect_CLayer2d& ACOverLayer) { // Store and disable current clipping planes - GLint maxplanes; - glGetIntegerv(GL_MAX_CLIP_PLANES, &maxplanes); - const GLenum lastid = GL_CLIP_PLANE0 + maxplanes; - OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[maxplanes]; + const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext(); + const Standard_Integer aMaxClipPlanes = aContext->MaxClipPlanes(); + const GLenum lastid = GL_CLIP_PLANE0 + aMaxClipPlanes; + OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[aMaxClipPlanes]; OPENGL_CLIP_PLANE *ptrPlane = oldPlanes; GLenum planeid = GL_CLIP_PLANE0; for ( ; planeid < lastid; planeid++, ptrPlane++ ) @@ -652,8 +652,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, glDisable( planeid ); ptrPlane->isEnabled = GL_TRUE; } - else + else + { ptrPlane->isEnabled = GL_FALSE; + } } ///////////////////////////////////////////////////////////////////////////// @@ -987,55 +989,42 @@ D = -[Px,Py,Pz] dot |Nx| // Apply clipping planes { - // Define starting plane id - planeid = GL_CLIP_PLANE0; - - GLdouble equation[4]; - if ( myZClip.Back.IsOn || myZClip.Front.IsOn ) { - // Apply front and back clipping planes - GLfloat mat[4][4]; - glMatrixMode( GL_MODELVIEW ); - glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat ); - glLoadIdentity(); + Graphic3d_SetOfHClipPlane aZClipping; const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd; if ( myZClip.Back.IsOn ) { const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd; - equation[0] = 0.0; /* Nx */ - equation[1] = 0.0; /* Ny */ - equation[2] = 1.0; /* Nz */ - equation[3] = -back; /* P dot N */ - glClipPlane( planeid, equation ); - glEnable( planeid ); - planeid++; + const Graphic3d_ClipPlane::Equation aBack(0.0, 0.0, 1.0, -back); + aZClipping.Add (new Graphic3d_ClipPlane (aBack)); } if ( myZClip.Front.IsOn ) { const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd; - equation[0] = 0.0; /* Nx */ - equation[1] = 0.0; /* Ny */ - equation[2] = -1.0; /* Nz */ - equation[3] = front; /* P dot N */ - glClipPlane( planeid, equation ); - glEnable( planeid ); - planeid++; + const Graphic3d_ClipPlane::Equation aFront (0.0, 0.0, -1.0, front); + aZClipping.Add (new Graphic3d_ClipPlane (aFront)); } - glLoadMatrixf( (GLfloat *) mat ); + aContext->ChangeClipping().Set (aZClipping, &OpenGl_IdentityMatrix); } // Apply user clipping planes - NCollection_List::Iterator planeIter(myClippingPlanes); - for ( ; planeIter.More(); planeIter.Next() ) + Graphic3d_SetOfHClipPlane aPlanesOn; + Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes); + for (; aPlaneIt.More(); aPlaneIt.Next()) { - glClipPlane( planeid, planeIter.Value().equation ); - glEnable( planeid ); - planeid++; + const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value(); + if (aUserPln->IsOn ()) + aPlanesOn.Add (aUserPln); + } + + if (aPlanesOn.Size() > 0) + { + aContext->ChangeClipping().Set (aPlanesOn); } } @@ -1122,9 +1111,8 @@ D = -[Px,Py,Pz] dot |Nx| // and invoking optional callbacks AWorkspace->ResetAppliedAspect(); - // Disable current clipping planes - for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ ) - glDisable( planeid ); + // Unset clip planes managed by driver + aContext->ChangeClipping().Unset (aContext->Clipping().Planes()); // display global trihedron if (myTrihedron != NULL) diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index a0c453cbd4..5045cae263 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index 351127a9b0..5caff56f19 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,7 @@ class OpenGl_AspectMarker; class OpenGl_AspectText; class OpenGl_FrameBuffer; class OpenGl_Structure; +class OpenGl_Element; class Image_PixMap; //! Reprepsents window with GL context. @@ -167,6 +169,28 @@ public: Standard_EXPORT Handle(OpenGl_Texture) EnableTexture (const Handle(OpenGl_Texture)& theTexture, const Handle(Graphic3d_TextureParams)& theParams = NULL); + //! Set filter for restricting rendering of particular elements. + //! Filter can be applied for rendering passes used by recursive + //! rendering algorithms for rendering elements of groups. + //! @param theFilter [in] the filter instance. + inline void SetRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter) + { + myRenderFilter = theFilter; + } + + //! Get rendering filter. + //! @return filter instance. + inline const Handle(OpenGl_RenderFilter)& GetRenderFilter() const + { + return myRenderFilter; + } + + //! @return applied view matrix. + inline const OpenGl_Matrix* ViewMatrix() const { return ViewMatrix_applied; } + + //! @return applied model structure matrix. + inline const OpenGl_Matrix* ModelMatrix() const { return StructureMatrix_applied; } + protected: void CopyBuffers (const Standard_Boolean theFrontToBack); @@ -202,6 +226,7 @@ protected: //! @name protected fields protected: //! @name fields related to status + Handle(OpenGl_RenderFilter) myRenderFilter; Handle(OpenGl_Texture) myTextureBound; //!< currently bound texture (managed by OpenGl_AspectFace and OpenGl_View environment texture) const OpenGl_AspectLine *AspectLine_set, *AspectLine_applied; const OpenGl_AspectFace *AspectFace_set, *AspectFace_applied; diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cdl b/src/PrsMgr/PrsMgr_PresentableObject.cdl index 50c27813ab..97dd501622 100755 --- a/src/PrsMgr/PrsMgr_PresentableObject.cdl +++ b/src/PrsMgr/PrsMgr_PresentableObject.cdl @@ -63,6 +63,8 @@ uses Transformation from Geom, ListOfInteger from TColStd, Location from TopLoc, + ClipPlane_Handle from Graphic3d, + SetOfHClipPlane from Graphic3d, -- ABD 29/10/04 Transform Persistence of Presentation( pan, zoom, rotate ) TransModeFlags from Graphic3d, Pnt from gp, @@ -249,11 +251,46 @@ is returns Integer from Standard is static; ---Purpose: Get ID of Z layer. If no presentations of object is displayed, -- and layer ID is unavailable, the -1 value is returned. - + + AddClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual; + ---Purpose: Adds clip plane for graphical clipping for all display mode + -- presentations. The composition of clip planes truncates the rendering + -- space to convex volume. Please be aware that number of supported + -- clip plane is limited. The planes which exceed the limit are ignored. + -- Besides of this, some planes can be already set in view where the object + -- is shown: the number of these planes should be substracted from limit + -- to predict the maximum possible number of object clipping planes. + -- @param thePlane [in] the clip plane to be appended to map of clip planes. + + RemoveClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual; + ---Purpose: Removes previously added clip plane. + -- @param thePlane [in] the clip plane to be removed from map of clip planes. + + SetClipPlanes (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is virtual; + ---Purpose: Set clip planes for graphical clipping for all display mode presentations. + -- The composition of clip planes truncates the rendering space to convex + -- volume. Please be aware that number of supported clip plane is limited. + -- The planes which exceed the limit are ignored. Besides of this, some + -- planes can be already set in view where the object is shown: the number + -- of these planes should be substracted from limit to predict the maximum + -- possible number of object clipping planes. + + GetClipPlanes (me) returns SetOfHClipPlane from Graphic3d; + ---C++: inline + ---C++: return const& + ---Purpose: Get clip planes. + -- @return set of previously added clip planes for all display mode presentations. + + UpdateClipping (me : mutable) is virtual protected; + ---Purpose: General virtual method for internal update of presentation state + -- when some modifications on list of clip planes occurs. Base + -- implementation propagate clip planes to every presentation. + fields myPresentations: Presentations from PrsMgr is protected; myTypeOfPresentation3d: TypeOfPresentation3d from PrsMgr is protected; myLocation : Location from TopLoc is protected; + myClipPlanes : SetOfHClipPlane from Graphic3d is protected; --myTransformPersistence : TransModeFlags from Graphic3d; myTransformPersistence : CTransPersStruct from Graphic3d; diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cxx b/src/PrsMgr/PrsMgr_PresentableObject.cxx index 83480044cd..a6ad5cc17f 100755 --- a/src/PrsMgr/PrsMgr_PresentableObject.cxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.cxx @@ -36,7 +36,6 @@ //function : PrsMgr_PresentableObject //purpose : //======================================================================= - PrsMgr_PresentableObject::PrsMgr_PresentableObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d) :myPresentations(),myTypeOfPresentation3d(aTypeOfPresentation3d) { @@ -46,25 +45,29 @@ PrsMgr_PresentableObject::PrsMgr_PresentableObject(const PrsMgr_TypeOfPresentati myTransformPersistence.Point.z = 0.0; } - //======================================================================= //function : Fill //purpose : //======================================================================= -void PrsMgr_PresentableObject::Fill(const Handle(PrsMgr_PresentationManager)& aPresentationManager, - const Handle(PrsMgr_Presentation)& aPresentation, - const Standard_Integer aMode) { - if (aPresentation->DynamicType() == STANDARD_TYPE(PrsMgr_Presentation3d)) { - Compute(((Handle(PrsMgr_PresentationManager3d)&)aPresentationManager),((Handle(PrsMgr_Presentation3d)&)aPresentation)->Presentation(),aMode); - UpdateLocation(((Handle(PrsMgr_Presentation3d)&)aPresentation)->Presentation()); - Handle(Graphic3d_Structure) aStruct = Handle(Graphic3d_Structure)::DownCast( ((Handle(PrsMgr_Presentation3d)&)aPresentation)->Presentation() ); - if ( !aStruct.IsNull() ) { - aStruct->SetTransformPersistence( GetTransformPersistenceMode(), GetTransformPersistencePoint() ); - } +void PrsMgr_PresentableObject::Fill (const Handle(PrsMgr_PresentationManager)& aPresentationManager, + const Handle(PrsMgr_Presentation)& aPresentation, + const Standard_Integer aMode) +{ + if (aPresentation->DynamicType() == STANDARD_TYPE (PrsMgr_Presentation3d)) + { + Handle(PrsMgr_PresentationManager3d) aPrsMgr3d = + (Handle(PrsMgr_PresentationManager3d)&)aPresentationManager; + Handle(PrsMgr_Presentation3d) aPrs3d = + (Handle(PrsMgr_Presentation3d)&)aPresentation; + Handle(Prs3d_Presentation) aStruct3d = aPrs3d->Presentation(); + + Compute (aPrsMgr3d, aStruct3d, aMode); + UpdateLocation (aStruct3d); + aStruct3d->SetClipPlanes (myClipPlanes); + aStruct3d->SetTransformPersistence (GetTransformPersistenceMode(), GetTransformPersistencePoint()); } } - //======================================================================= //function : Compute //purpose : @@ -75,6 +78,7 @@ void PrsMgr_PresentableObject::Compute(const Handle(PrsMgr_PresentationManager3d { Standard_NotImplemented::Raise("cannot compute in a 3d visualizer"); } + //======================================================================= //function : Compute //purpose : @@ -84,6 +88,7 @@ void PrsMgr_PresentableObject::Compute(const Handle(Prs3d_Projector)& /*aProject { Standard_NotImplemented::Raise("cannot compute under a specific projector"); } + //======================================================================= //function : Compute //purpose : @@ -116,11 +121,11 @@ void PrsMgr_PresentableObject::Update (const Standard_Boolean AllModes) { } } } + //======================================================================= //function : Update //purpose : //======================================================================= - void PrsMgr_PresentableObject::Update (const Standard_Integer aMode, const Standard_Boolean ClearOther) { Standard_Integer l = myPresentations.Length(); for (Standard_Integer i=1; i <= l; i++) { @@ -149,11 +154,11 @@ void PrsMgr_PresentableObject::Update (const Standard_Integer aMode, const Stand } } + //======================================================================= //function : Presentations //purpose : //======================================================================= - PrsMgr_Presentations& PrsMgr_PresentableObject::Presentations() { return myPresentations; } @@ -162,18 +167,15 @@ PrsMgr_Presentations& PrsMgr_PresentableObject::Presentations() { //function : HasLocation //purpose : //======================================================================= - Standard_Boolean PrsMgr_PresentableObject::HasLocation() const { - return !Location().IsIdentity();} - - + return !Location().IsIdentity(); +} //======================================================================= //function : SetToUpdate //purpose : //======================================================================= - void PrsMgr_PresentableObject::SetToUpdate(const Standard_Integer aMode) { for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){ @@ -181,6 +183,11 @@ void PrsMgr_PresentableObject::SetToUpdate(const Standard_Integer aMode) myPresentations(IP).Presentation()->SetUpdateStatus(Standard_True); } } + +//======================================================================= +//function : SetToUpdate +//purpose : +//======================================================================= void PrsMgr_PresentableObject::SetToUpdate() { for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){ @@ -213,7 +220,6 @@ void PrsMgr_PresentableObject::ToBeUpdated(TColStd_ListOfInteger& OutList) const //function : SetTypeOfPresentation //purpose : //======================================================================= - void PrsMgr_PresentableObject::SetTypeOfPresentation(const PrsMgr_TypeOfPresentation3d aType) { myTypeOfPresentation3d = aType; @@ -258,6 +264,10 @@ void PrsMgr_PresentableObject::ResetLocation() myLocation = aLoc; } +//======================================================================= +//function : UpdateLocation +//purpose : +//======================================================================= void PrsMgr_PresentableObject::UpdateLocation() { if(!HasLocation()) return; @@ -271,12 +281,10 @@ void PrsMgr_PresentableObject::UpdateLocation() } } - //======================================================================= //function : UpdateLocation //purpose : //======================================================================= - void PrsMgr_PresentableObject::UpdateLocation(const Handle(Prs3d_Presentation)& P) { if(myLocation.IsIdentity()) return; @@ -363,3 +371,63 @@ Standard_Integer PrsMgr_PresentableObject::GetZLayer return -1; } + +// ======================================================================= +// function : AddClipPlane +// purpose : +// ======================================================================= +void PrsMgr_PresentableObject::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) +{ + myClipPlanes.Add (thePlane); + + UpdateClipping(); // process changes +} + +// ======================================================================= +// function : RemoveClipPlane +// purpose : +// ======================================================================= +void PrsMgr_PresentableObject::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) +{ + myClipPlanes.Remove (thePlane); + + UpdateClipping(); // process changes +} + +// ======================================================================= +// function : SetClipPlanes +// purpose : +// ======================================================================= +void PrsMgr_PresentableObject::SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes) +{ + myClipPlanes = thePlanes; + + UpdateClipping(); +} + +// ======================================================================= +// function : UpdateClipping +// purpose : +// ======================================================================= +void PrsMgr_PresentableObject::UpdateClipping() +{ + // affect generated structures + for (Standard_Integer aPrsIt = 1; aPrsIt <= myPresentations.Length(); ++aPrsIt) + { + // pass over presentation manager 3d mechanism right to the structures - + // we do not interested in display mode collections. + const PrsMgr_ModedPresentation& aModedPrs = myPresentations (aPrsIt); + + Handle(PrsMgr_Presentation3d) aPrs = + Handle(PrsMgr_Presentation3d)::DownCast (aModedPrs.Presentation()); + + if (aPrs.IsNull()) + continue; + + Handle(Prs3d_Presentation) aStruct3d = aPrs->Presentation(); + if (aStruct3d.IsNull()) + continue; + + aStruct3d->SetClipPlanes (myClipPlanes); + } +} diff --git a/src/PrsMgr/PrsMgr_PresentableObject.lxx b/src/PrsMgr/PrsMgr_PresentableObject.lxx index b056ee7ff4..3edbbe7305 100755 --- a/src/PrsMgr/PrsMgr_PresentableObject.lxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.lxx @@ -25,3 +25,8 @@ inline PrsMgr_TypeOfPresentation3d PrsMgr_PresentableObject::TypeOfPresentation3 inline const TopLoc_Location& PrsMgr_PresentableObject::Location() const {return myLocation;} + +inline const Graphic3d_SetOfHClipPlane& PrsMgr_PresentableObject::GetClipPlanes() const +{ + return myClipPlanes; +} diff --git a/src/QABugs/QABugs_3.cxx b/src/QABugs/QABugs_3.cxx index f77883dd91..1685155955 100644 --- a/src/QABugs/QABugs_3.cxx +++ b/src/QABugs/QABugs_3.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -683,97 +684,9 @@ static Standard_Integer BUC60574(Draw_Interpretor& di, Standard_Integer /*n*/, c #include #include -#include #include #include -static Standard_Integer BUC60698(Draw_Interpretor& di, Standard_Integer argc, const char ** a) -{ - if(argc > 2) { - di << "Usage : " << a[0] << " [BRepAlgoAPI/BRepAlgo = 1/0]" << "\n"; - return 1; - } - Standard_Boolean IsBRepAlgoAPI = Standard_True; - if (argc == 2) { - Standard_Integer IsB = Draw::Atoi(a[1]); - if (IsB != 1) { - IsBRepAlgoAPI = Standard_False; -#if ! defined(BRepAlgo_def01) -// di << "Error: There is not BRepAlgo_Fuse class" << "\n"; -// return 1; -#endif - } - } - - Handle(AIS_InteractiveContext) myAISContext = ViewerTest::GetAISContext(); - if(myAISContext.IsNull()) { - di << "use 'vinit' command before " << a[0] << "\n"; - return -1; - } - TopoDS_Solid box = BRepPrimAPI_MakeBox(1,1,1).Solid(); - TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(0.5,0.5,0.5),0.6).Shape(); - -//#if ! defined(BRepAlgoAPI_def01) -// TopoDS_Shape fuse = BRepAlgoAPI_Fuse(box,sphere).Shape(); -//#else -// TopoDS_Shape fuse = BRepAlgo_Fuse(box,sphere).Shape(); -//#endif - - TopoDS_Shape fuse; - if (IsBRepAlgoAPI) { - di << "fuse = BRepAlgoAPI_Fuse(box,sphere).Shape()" <<"\n"; - fuse = BRepAlgoAPI_Fuse(box,sphere).Shape(); - } else { - di << "fuse = BRepAlgo_Fuse(box,sphere).Shape()" <<"\n"; - fuse = BRepAlgo_Fuse(box,sphere).Shape(); - } - - Handle_AIS_Shape theAISShape = new AIS_Shape(fuse); - myAISContext->Display(theAISShape); - di.Eval("vfit"); - gp_Pln thegpPln = gce_MakePln(gp_Pnt(0.5,0.5,0.5),gp_Dir(0,0,1)); - Standard_Real A,B,C,D; - thegpPln.Coefficients(A,B,C,D); - Handle_V3d_Plane thePlane = new V3d_Plane(A,B,C,D); - myAISContext->CurrentViewer()->AddPlane (thePlane); // add to defined planes list - for (myAISContext->CurrentViewer()->InitActiveViews(); - myAISContext->CurrentViewer()->MoreActiveViews (); - myAISContext->CurrentViewer()->NextActiveViews ()) { - try { - OCC_CATCH_SIGNALS - myAISContext->CurrentViewer()->ActiveView()->SetPlaneOn(thePlane); - } - catch(Standard_Failure) { - di << "SetPlaneOn catched 1" << "\n"; - } -#ifdef WNT - catch(...) { - di << "SetPlaneOn catched 1" << "\n"; - } -#endif - }//ActiveView loop - for (myAISContext->CurrentViewer()->InitDefinedViews(); - myAISContext->CurrentViewer()->MoreDefinedViews (); - myAISContext->CurrentViewer()->NextDefinedViews ()) { - try { - OCC_CATCH_SIGNALS - myAISContext->CurrentViewer()->DefinedView()->SetPlaneOn(thePlane); - } - catch(Standard_Failure) { - di << "SetPlaneOn catched 1" << "\n"; - } -#ifdef WNT - catch(...) { - di << "SetPlaneOn catched 2" << "\n"; - } -#endif - }//DefinedView loop - myAISContext->UpdateCurrentViewer(); - myAISContext->OpenLocalContext(); - myAISContext->ActivateStandardMode(TopAbs_FACE); - return 0; -} - static Standard_Integer BUC60699(Draw_Interpretor& di, Standard_Integer /*n*/, const char ** a) { @@ -2239,8 +2152,6 @@ void QABugs::Commands_3(Draw_Interpretor& theCommands) { theCommands.Add("PRO19626","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol",__FILE__,ksection,group); theCommands.Add("BUC60574","BUC60574 ",__FILE__,BUC60574,group); - theCommands.Add("BUC60698","BUC60698 [BRepAlgoAPI/BRepAlgo = 1/0]",__FILE__,BUC60698,group); - theCommands.Add("BUC60699","BUC60699 ",__FILE__,BUC60699,group); theCommands.Add("GER61394","GER61394 [1/0]",__FILE__,GER61394,group); theCommands.Add("GER61351","GER61351 name/object name/r g b/object r g b",__FILE__,setcolor,group); diff --git a/src/Select3D/Select3D_Projector.cdl b/src/Select3D/Select3D_Projector.cdl index d2493869e2..42ad63a078 100755 --- a/src/Select3D/Select3D_Projector.cdl +++ b/src/Select3D/Select3D_Projector.cdl @@ -193,23 +193,6 @@ is -- 2d point . is virtual; - DepthMin(me) returns Real from Standard; - ---Purpose: Returns the minimum depth value (if clipping plane defined). - --- Should be used when call ::Shoot() to compute eyeline. - ---C++: inline - - DepthMax(me) returns Real from Standard; - ---Purpose: Returns the maximum depth value (if clipping plane defined). - --- Should be used when call ::Shoot() to compute eyeline. - ---C++: inline - - DepthMinMax(me : mutable; - theDepthMin : in Real from Standard; - theDepthMax : in Real from Standard); - ---Purpose: Setup the min/max depth values (doesn't affect - --- projection functionality itself). - --- Should be used when call ::Shoot() to compute eyeline. - Transform(me; P : in out Pnt from gp; T : GTrsf from gp) ---C++: inline @@ -230,7 +213,5 @@ fields myInvTrsf : GTrsf from gp is protected; myView : View from V3d; - myDepthMin : Real from Standard; - myDepthMax : Real from Standard; end Projector; diff --git a/src/Select3D/Select3D_Projector.cxx b/src/Select3D/Select3D_Projector.cxx index 3a897e9059..1d42e4c0c1 100755 --- a/src/Select3D/Select3D_Projector.cxx +++ b/src/Select3D/Select3D_Projector.cxx @@ -44,9 +44,7 @@ Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou) : myPersp(aViou->Type()==V3d_PERSPECTIVE), myFocus(aViou->Focale()), - myView(aViou), - myDepthMin(-Precision::Infinite()), - myDepthMax( Precision::Infinite()) + myView(aViou) { Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ; //Standard_Boolean Pers=Standard_False; @@ -72,9 +70,7 @@ Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou) Select3D_Projector::Select3D_Projector() : myPersp(Standard_False), - myFocus(0), - myDepthMin(-Precision::Infinite()), - myDepthMax( Precision::Infinite()) + myFocus(0) { Scaled(); } @@ -86,9 +82,7 @@ Select3D_Projector::Select3D_Projector() Select3D_Projector::Select3D_Projector (const gp_Ax2& CS) : myPersp(Standard_False), - myFocus(0), - myDepthMin(-Precision::Infinite()), - myDepthMax( Precision::Infinite()) + myFocus(0) { myScaledTrsf.SetTransformation(CS); myGTrsf.SetTrsf(myScaledTrsf); @@ -103,9 +97,7 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS) Select3D_Projector::Select3D_Projector (const gp_Ax2& CS, const Standard_Real Focus) : myPersp(Standard_True), - myFocus(Focus), - myDepthMin(-Precision::Infinite()), - myDepthMax( Precision::Infinite()) + myFocus(Focus) { myScaledTrsf.SetTransformation(CS); myGTrsf.SetTrsf(myScaledTrsf); @@ -122,9 +114,7 @@ Select3D_Projector::Select3D_Projector (const gp_Trsf& T, const Standard_Real Focus) : myPersp(Persp), myFocus(Focus), - myScaledTrsf(T), - myDepthMin(-Precision::Infinite()), - myDepthMax( Precision::Infinite()) + myScaledTrsf(T) { myGTrsf.SetTrsf(myScaledTrsf); Scaled(); @@ -140,9 +130,7 @@ Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT, const Standard_Real Focus) : myPersp(Persp), myFocus(Focus), - myGTrsf(GT), - myDepthMin(-Precision::Infinite()), - myDepthMax( Precision::Infinite()) + myGTrsf(GT) { Scaled(); } @@ -463,10 +451,3 @@ void Select3D_Projector::SetView(const Handle(V3d_View)& aViou) Scaled(); } - -void Select3D_Projector::DepthMinMax (const Standard_Real theDepthMin, - const Standard_Real theDepthMax) -{ - myDepthMin = theDepthMin; - myDepthMax = theDepthMax; -} diff --git a/src/Select3D/Select3D_Projector.lxx b/src/Select3D/Select3D_Projector.lxx index a424272052..6710e1df77 100755 --- a/src/Select3D/Select3D_Projector.lxx +++ b/src/Select3D/Select3D_Projector.lxx @@ -126,13 +126,3 @@ inline void Select3D_Projector::Transform (gp_Pnt& Pnt, const gp_GTrsf& T) const T.Transforms(xyz); Pnt = gp_Pnt(xyz); } - -inline Standard_Real Select3D_Projector::DepthMin() const -{ - return myDepthMin; -} - -inline Standard_Real Select3D_Projector::DepthMax() const -{ - return myDepthMax; -} diff --git a/src/Select3D/Select3D_SensitiveBox.cdl b/src/Select3D/Select3D_SensitiveBox.cdl index b47d4a798a..8bfbee94ed 100755 --- a/src/Select3D/Select3D_SensitiveBox.cdl +++ b/src/Select3D/Select3D_SensitiveBox.cdl @@ -35,6 +35,7 @@ uses Lin from gp, EntityOwner from SelectBasics, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt2d from TColgp, Location from TopLoc @@ -71,17 +72,16 @@ is GetConnected(me:mutable;aLocation: Location from TopLoc) returns SensitiveEntity from Select3D is redefined static; - - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is static; - ---Level: Public - ---Purpose: - -- - + + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. + Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; aTol: Real from Standard) @@ -97,7 +97,7 @@ is ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; + returns Real from Standard; Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; diff --git a/src/Select3D/Select3D_SensitiveBox.cxx b/src/Select3D/Select3D_SensitiveBox.cxx index c2cf79a9fb..8945fa1725 100755 --- a/src/Select3D/Select3D_SensitiveBox.cxx +++ b/src/Select3D/Select3D_SensitiveBox.cxx @@ -65,8 +65,6 @@ Select3D_SensitiveEntity(OwnerId) void Select3D_SensitiveBox:: Project(const Handle(Select3D_Projector)& aProj) { - Select3D_SensitiveEntity::Project(aProj); // to set the field last proj... - if(HasLocation()) { Bnd_Box B = mybox3d.Transformed(Location().Transformation()); @@ -103,15 +101,20 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected(const TopLo // Function: Matches // Purpose : //================================================== -Standard_Boolean Select3D_SensitiveBox:: -Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) + +Standard_Boolean Select3D_SensitiveBox::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { - Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); - DMin=0.; - + // check that sensitive box passes by depth + Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine()); + if (thePickArgs.IsClipped (aDepth)) + { + return Standard_False; + } + + theMatchDMin = 0.0; + theMatchDepth = aDepth; return Standard_True; } diff --git a/src/Select3D/Select3D_SensitiveCircle.cdl b/src/Select3D/Select3D_SensitiveCircle.cdl index 31baa521d6..53e6cce8cf 100755 --- a/src/Select3D/Select3D_SensitiveCircle.cdl +++ b/src/Select3D/Select3D_SensitiveCircle.cdl @@ -34,6 +34,7 @@ uses Lin from gp, EntityOwner from SelectBasics, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Circle from Geom, Array1OfPnt from TColgp, HArray1OfPnt from TColgp, @@ -95,12 +96,14 @@ is -- If the length of apolyg3d is more then 1, the first point of apolyg3d -- must be equal to the last point of apolyg3d. - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is static; + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -117,9 +120,16 @@ is ---Level: Public - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; - + ComputeDepth (me; + thePickLine : Lin from gp; + theDetectedIndex : Integer from Standard) + returns Real from Standard; + ---Level: Public + ---Purpose: Compute depth of sensitive circle for the detected sub-part. + -- @param thePickLine [in] the picking line. + -- @param theDetectedIndex [in] index of the detected sub-part. + -- @return depth on the picking line. + ArrayBounds(me;Low,Up:in out Integer); GetPoint3d(me;rank:Integer) returns Pnt from gp; @@ -142,7 +152,6 @@ is fields myFillStatus : Boolean; - myDetectedIndex : Integer from Standard; -- used for depth... myCenter2D : Pnt2d from Select3D; -- used for Matches() myCenter3D : Pnt from Select3D; -- used for Matches() myCircle : Circle from Geom; diff --git a/src/Select3D/Select3D_SensitiveCircle.cxx b/src/Select3D/Select3D_SensitiveCircle.cxx index 66288e7501..aebb29721c 100755 --- a/src/Select3D/Select3D_SensitiveCircle.cxx +++ b/src/Select3D/Select3D_SensitiveCircle.cxx @@ -72,7 +72,6 @@ Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId, const Standard_Integer NbPoints): Select3D_SensitivePoly(OwnerId, S3D_GetCircleNBPoints(TheCircle,NbPoints)), myFillStatus(FilledCircle), -myDetectedIndex(-1), myCircle(TheCircle), mystart(0), myend(0) @@ -129,7 +128,6 @@ Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId, const Standard_Integer NbPoints): Select3D_SensitivePoly(OwnerId, S3D_GetArcNBPoints(TheCircle,NbPoints)), myFillStatus(FilledCircle), -myDetectedIndex(-1), myCircle(TheCircle), mystart(u1), myend(u2) @@ -186,7 +184,6 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent const Standard_Boolean FilledCircle): Select3D_SensitivePoly(OwnerId, Thepolyg3d), myFillStatus(FilledCircle), -myDetectedIndex(-1), mystart(0), myend(0) { @@ -206,7 +203,6 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent const Standard_Boolean FilledCircle): Select3D_SensitivePoly(OwnerId, Thepolyg3d), myFillStatus(FilledCircle), -myDetectedIndex(-1), mystart(0), myend(0) { @@ -221,13 +217,13 @@ myend(0) //purpose : //======================================================================= -Standard_Boolean Select3D_SensitiveCircle:: -Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitiveCircle::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { Standard_Integer aSize = mypolyg.Size(); + Standard_Integer aDetectedIndex = -1; + gp_XY aPickXY (thePickArgs.X(), thePickArgs.Y()); if (aSize != 1) { Standard_Boolean Found = Standard_False; @@ -241,15 +237,19 @@ Matches(const Standard_Real X, Select3D_SensitiveTriangle::Status(mypolyg.Pnt2d(anIndex), mypolyg.Pnt2d(anIndex+1), mypolyg.Pnt2d(anIndex+2), - gp_XY(X,Y),aTol,DMin); + aPickXY, thePickArgs.Tolerance(), + theMatchDMin); Found = (TheStat != 2); - if(Found) myDetectedIndex = anIndex; + if (Found) + { + aDetectedIndex = anIndex; + } + anIndex += 2; } } else { - myDetectedIndex =-1; Standard_Real Xmin,Ymin,Xmax,Ymax; // Get coordinates of the bounding box @@ -259,32 +259,47 @@ Matches(const Standard_Real X, // Fill anArrayOf2dPnt with points from mypolig2d Points2D(anArrayOf2dPnt); - CSLib_Class2d anInOutTool(anArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax); + CSLib_Class2d anInOutTool (anArrayOf2dPnt, + thePickArgs.Tolerance(), + thePickArgs.Tolerance(), + Xmin, Ymin, Xmax, Ymax); // Method SiDans returns the status : // 1 - the point is inside the circle // 0 - the point is on the circle // -1 - the point is outside the circle - Standard_Integer aStat = anInOutTool.SiDans(gp_Pnt2d(X,Y)); + Standard_Integer aStat = anInOutTool.SiDans (gp_Pnt2d (aPickXY)); if(aStat != -1) { // Compute DMin (a distance between the center and the point) - DMin = gp_XY(myCenter2D.x - X, myCenter2D.y - Y).Modulus(); - Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); - return Standard_True; + theMatchDMin = gp_XY (myCenter2D.x - aPickXY.X(), myCenter2D.y - aPickXY.Y()).Modulus(); + + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex); + + return !thePickArgs.IsClipped (theMatchDepth); } + return Standard_False; } - if(!Found) - myDetectedIndex=-1; - else - Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); - return Found; + + if (Found) + { + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex); + + return !thePickArgs.IsClipped (theMatchDepth); + } + + return Standard_False; } + // Circle degenerates into point - DMin = gp_Pnt2d(X, Y).Distance(mypolyg.Pnt2d(0)); - if (DMin <= aTol*SensitivityFactor()) - return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); + theMatchDMin = gp_Pnt2d(aPickXY).Distance(mypolyg.Pnt2d(0)); + if (theMatchDMin <= thePickArgs.Tolerance() * SensitivityFactor()) + { + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex); + + return !thePickArgs.IsClipped (theMatchDepth); + } return Standard_False; } @@ -301,7 +316,6 @@ Matches(const Standard_Real XMin, const Standard_Real YMax, const Standard_Real aTol) { - myDetectedIndex =-1; Bnd_Box2d abox; abox.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax)); abox.Enlarge(aTol); @@ -324,7 +338,6 @@ Matches (const TColgp_Array1OfPnt2d& aPoly, const Bnd_Box2d& aBox, const Standard_Real aTol) { - myDetectedIndex = -1; Standard_Real Umin,Vmin,Umax,Vmax; aBox.Get(Umin,Vmin,Umax,Vmax); CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax); @@ -401,21 +414,23 @@ void Select3D_SensitiveCircle::Dump(Standard_OStream& S,const Standard_Boolean F //purpose : //======================================================================= -Standard_Real Select3D_SensitiveCircle::ComputeDepth(const gp_Lin& EyeLine) const +Standard_Real Select3D_SensitiveCircle::ComputeDepth (const gp_Lin& thePickLine, + const Standard_Integer theDetectedIndex) const { gp_XYZ aCDG; - if(myDetectedIndex==-1) + if (theDetectedIndex == -1) { aCDG = myCenter3D; } else { - aCDG += mypolyg.Pnt(myDetectedIndex); - aCDG += mypolyg.Pnt(myDetectedIndex+1); - aCDG += mypolyg.Pnt(myDetectedIndex+2); + aCDG += mypolyg.Pnt (theDetectedIndex); + aCDG += mypolyg.Pnt (theDetectedIndex + 1); + aCDG += mypolyg.Pnt (theDetectedIndex + 2); aCDG /= 3.; } - return ElCLib::Parameter(EyeLine,gp_Pnt(aCDG)); + + return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG)); } //======================================================================= diff --git a/src/Select3D/Select3D_SensitiveCurve.cdl b/src/Select3D/Select3D_SensitiveCurve.cdl index 0895a03eb8..b8f0aeb8fc 100755 --- a/src/Select3D/Select3D_SensitiveCurve.cdl +++ b/src/Select3D/Select3D_SensitiveCurve.cdl @@ -36,6 +36,7 @@ uses Lin from gp, EntityOwner from SelectBasics, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Curve from Geom, Array1OfPnt from TColgp, Array1OfPnt2d from TColgp, @@ -72,13 +73,15 @@ is ---Level: Public ---Purpose: Creation of Sensitive Curve from Points. -- Warning : This Method should disappear in the next version... - - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is redefined static; + + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -95,9 +98,15 @@ is ---Level: Public - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; - + ComputeDepth (me; + thePickLine : Lin from gp; + theDetectedIndex : Integer from Standard) + returns Real from Standard; + ---Level: Public + ---Purpose: Compute depth of sensitive circle for the detected sub-part. + -- @param thePickLine [in] the picking line. + -- @param theDetectedIndex [in] index of the detected sub-part. + -- @return depth on the picking line. GetLastDetected(me) returns Integer from Standard; ---Purpose: Gets index of last detected segment diff --git a/src/Select3D/Select3D_SensitiveCurve.cxx b/src/Select3D/Select3D_SensitiveCurve.cxx index 5965a338f5..a873964bad 100755 --- a/src/Select3D/Select3D_SensitiveCurve.cxx +++ b/src/Select3D/Select3D_SensitiveCurve.cxx @@ -76,25 +76,27 @@ mylastseg(0) // Purpose : //================================================== -Standard_Boolean Select3D_SensitiveCurve -::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { Standard_Integer Rank; TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size()); Points2D(aArrayOf2dPnt); if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt, - X, Y, - aTol, - DMin, + thePickArgs.X(), thePickArgs.Y(), + thePickArgs.Tolerance(), + theMatchDMin, Rank)) { + // remember detected segment (for GetLastDetected) mylastseg = Rank; - // compute and validate the depth (::Depth()) along the eyeline - return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin); + + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank); + + return !thePickArgs.IsClipped (theMatchDepth); } + return Standard_False; } @@ -189,29 +191,30 @@ void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean Fu //purpose : //======================================================================= -Standard_Real Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& EyeLine) const +Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine, + const Standard_Integer theSegment) const { - Standard_Real aDepth = Precision::Infinite(); - - // Not implemented - if(mylastseg==0) - return aDepth; - - gp_XYZ aCDG; - // In case if mylastseg and mylastseg+1 are not valid - // the depth will be infinite - if (mylastseg < mypolyg.Size()) + if (theSegment == 0) { - aCDG = mypolyg.Pnt(mylastseg); - if (mylastseg+1 < mypolyg.Size()) - { - aCDG += mypolyg.Pnt(mylastseg+1); - aCDG /= 2.; - } - aDepth = ElCLib::Parameter(EyeLine,gp_Pnt(aCDG)); + return Precision::Infinite(); } - return aDepth; + // In case if theSegment and theSegment + 1 are not valid + // the depth will be infinite + if (theSegment >= mypolyg.Size()) + { + return Precision::Infinite(); + } + + gp_XYZ aCDG = mypolyg.Pnt (theSegment); + + if (theSegment + 1 < mypolyg.Size()) + { + aCDG += mypolyg.Pnt(theSegment + 1); + aCDG /= 2.; + } + + return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG)); } //======================================================================= diff --git a/src/Select3D/Select3D_SensitiveEntity.cdl b/src/Select3D/Select3D_SensitiveEntity.cdl index 92c7a184ba..b7bd33cd49 100755 --- a/src/Select3D/Select3D_SensitiveEntity.cdl +++ b/src/Select3D/Select3D_SensitiveEntity.cdl @@ -59,14 +59,12 @@ is Is3D(me) returns Boolean from Standard is redefined static; ---Purpose: Returns true if this framework provides 3D information. - Project (me:mutable;aProjector : Projector from Select3D) is virtual; + Project (me:mutable;aProjector : Projector from Select3D) is deferred; ---Level: Public - ---Purpose:Returns the projector aProjector. - -- In classes inheriting this framework, you must - -- redefine this function in order to get a sensitive 2D - -- rectangle from a 3D entity. This rectangle is the - -- sensitive zone which makes the 3D entity selectable. - + ---Purpose: In classes inheriting this framework, you must + -- redefine this function in order to get a sensitive 2D + -- rectangle from a 3D entity. This rectangle is the + -- sensitive zone which makes the 3D entity selectable. MaxBoxes(me) returns Integer is redefined virtual; ---Level: Public @@ -87,16 +85,6 @@ is -- sensitive entity which can accept another connected -- sensitive entity.//can be connected to another sensitive entity. - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean is redefined virtual; - ---Purpose: Matches the coordinates X, Y with the entity found at - -- that point within the tolerance aTol and the minimum depth DMin. - -- You must redefine this function for every inheriting entity. - -- You will have to call this framework inside the redefined function. - Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; aTol: Real from Standard) @@ -117,23 +105,6 @@ is returns Boolean from Standard is redefined virtual; ---Purpose: prevents from hiding virtual methods... - - GetEyeLine(me; X,Y : Real from Standard) returns Lin from gp; - ---Purpose: Returns the eye line for the point defined by the coordinates X,Y. - - ComputeDepth(me;EyeLine : Lin from gp) returns Real from Standard - is deferred; - ---Purpose: Returns the depth of this object on the line EyeLine. - -- EyeLine goes through the eye towards a point - -- defined by the coordinates X,Y in the function GetEyeLine. - ---Purpose: gives an abcissa on . - -- represents the line going through - -- the eye towards an X,Y point on the screen. This Method - -- must return a mean Depth on this line. - - - Depth(me) returns Real from Standard is redefined; - ---Category: Location of sensitive entities... -- Default implementations of HasLocation() and Location() rely on -- location obtained from the entity owner, to minimize memory usage. @@ -159,15 +130,6 @@ is UpdateLocation(me:mutable;aLoc:Location from TopLoc); - - SetLastPrj(me:mutable;aPrj:Projector from Select3D) is virtual; - - SetLastDepth(me:mutable; aDepth: Real from Standard) is protected; - -fields - - mylastprj : Projector from Select3D is protected; - mylastdepth : ShortReal from Standard; end SensitiveEntity; diff --git a/src/Select3D/Select3D_SensitiveEntity.cxx b/src/Select3D/Select3D_SensitiveEntity.cxx index 145671c977..6e459098d1 100755 --- a/src/Select3D/Select3D_SensitiveEntity.cxx +++ b/src/Select3D/Select3D_SensitiveEntity.cxx @@ -33,44 +33,9 @@ //======================================================================= Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId): -SelectBasics_SensitiveEntity(OwnerId), -mylastprj(), -mylastdepth(ShortRealLast()) +SelectBasics_SensitiveEntity(OwnerId) {} -//======================================================================= -//function : Project -//purpose : -//======================================================================= - -void Select3D_SensitiveEntity::Project(const Handle(Select3D_Projector)& aPrj) -{ - mylastprj = aPrj; -} - -//======================================================================= -//function : Matches -//purpose : -//======================================================================= - -Standard_Boolean Select3D_SensitiveEntity::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real /*aTol*/, - Standard_Real& /*DMin*/) -{ - if (!mylastprj.IsNull()) - { - gp_Lin L = mylastprj->Shoot (X, Y); - SetLastDepth (ComputeDepth (L)); - return (mylastdepth > mylastprj->DepthMin()) && (mylastdepth < mylastprj->DepthMax()); - } - else - { - SetLastDepth (ComputeDepth (gp_Lin())); // how we determine depth without eyeline here? - return (mylastdepth > ShortRealFirst()) && (mylastdepth < ShortRealLast()); - } -} - //======================================================================= //function : Matches //purpose : @@ -189,30 +154,6 @@ Standard_Boolean Select3D_SensitiveEntity::HasLocation() const Standard_Boolean Select3D_SensitiveEntity::Is3D() const {return Standard_True;} -//======================================================================= -//function : Depth -//purpose : -//======================================================================= - -Standard_Real Select3D_SensitiveEntity::Depth() const -{return mylastdepth;} - -//======================================================================= -//function : GetEyeLine -//purpose : -//======================================================================= - -gp_Lin Select3D_SensitiveEntity::GetEyeLine(const Standard_Real X, - const Standard_Real Y) const -{ - gp_Lin L; - if (!mylastprj.IsNull()) - { - L = mylastprj->Shoot (X, Y); - } - return L; -} - //======================================================================= //function : MaxBoxes //purpose : @@ -221,15 +162,6 @@ gp_Lin Select3D_SensitiveEntity::GetEyeLine(const Standard_Real X, Standard_Integer Select3D_SensitiveEntity::MaxBoxes() const {return 1;} -//======================================================================= -//function : SetLastPrj -//purpose : -//======================================================================= - -void Select3D_SensitiveEntity::SetLastPrj(const Handle(Select3D_Projector)& aprj) -{ mylastprj = aprj; } - - //======================================================================= //function : GetConnected //purpose : @@ -240,12 +172,3 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected(const To Handle(Select3D_SensitiveEntity) NiouEnt; return NiouEnt; } - -//======================================================================= -//function : SetLastDepth -//purpose : -//======================================================================= -void Select3D_SensitiveEntity::SetLastDepth(const Standard_Real aDepth) -{ - mylastdepth = DToF(aDepth); -} diff --git a/src/Select3D/Select3D_SensitiveFace.cdl b/src/Select3D/Select3D_SensitiveFace.cdl index 1d783d5e6b..cc53659b72 100755 --- a/src/Select3D/Select3D_SensitiveFace.cdl +++ b/src/Select3D/Select3D_SensitiveFace.cdl @@ -32,6 +32,7 @@ uses Projector from Select3D, Lin from gp, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt from TColgp, HArray1OfPnt from TColgp, Array1OfPnt2d from TColgp, @@ -66,12 +67,14 @@ is -- the sensitivity type Sensitivity. -- The array of points is the outer polygon of the geometric face. - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is redefined virtual; + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined virtual; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -89,14 +92,22 @@ is ---Level: Public - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined virtual; + ComputeDepth (me; + thePickLine : Lin from gp; + theDepthMin, theDepthMax : Real from Standard) + returns Real from Standard + is virtual; ---Level: Public ---Purpose: Computes the depth values for all 3D points defining this face and returns - -- the minimal value among them. + -- the minimal value among them. -- If the "minimal depth" approach is not suitable and gives wrong detection results - -- in some particular case, a custom sensitive face class can be implemented at application level - -- that overrides default ComputeDepth() behavior. + -- in some particular case, a custom sensitive face class can redefine this method. + + ComputeDepth(me;EyeLine: Lin from gp) + is private; + ---Level: Public + ---Purpose: Warning: Obsolete. + -- Use newer version of the method with min, max limits passed as arguments. Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; @@ -110,6 +121,4 @@ is fields mytype : TypeOfSensitivity; - myautointer : Boolean; - end SensitiveFace; diff --git a/src/Select3D/Select3D_SensitiveFace.cxx b/src/Select3D/Select3D_SensitiveFace.cxx index 524c40f4ee..d45cde8e17 100755 --- a/src/Select3D/Select3D_SensitiveFace.cxx +++ b/src/Select3D/Select3D_SensitiveFace.cxx @@ -32,18 +32,6 @@ #include - -#define AutoInterMask 0x01 -#define AutoComputeMask 0x02 -// Standard_True if the flag is one -#define AutoInterFlag(aflag) ( aflag & AutoInterMask ) -#define AutoComputeFlag(aflag) ( aflag & AutoComputeMask ) -// set the flag to one -#define SetAutoInterFlag(aflag) ( aflag = aflag & AutoInterMask) -#define SetAutoComputeFlag(aflag) ( aflag = aflag & AutoComputeMask) -// Initialize flags -#define AutoInitFlags(aflag) (aflag = 0) - //================================================== // Function: Hide this constructor to the next version... // Purpose : simply avoid interfering with the version update @@ -56,7 +44,6 @@ Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId, Select3D_SensitivePoly(OwnerId, ThePoints), mytype (aType) { - AutoInitFlags(myautointer); } //================================================== @@ -71,7 +58,6 @@ Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId, Select3D_SensitivePoly(OwnerId, ThePoints), mytype (aType) { - AutoInitFlags(myautointer); } //================================================== @@ -79,11 +65,9 @@ mytype (aType) // Purpose : //================================================== -Standard_Boolean Select3D_SensitiveFace:: -Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { Standard_Real DMin2 = 0.; Standard_Real Xmin = 0.,Ymin = 0.,Xmax = 0.,Ymax = 0.; @@ -96,7 +80,7 @@ Matches(const Standard_Real X, // from start Dmin = size of the bounding box 2D, // then min. distance of the polyhedron or cdg... - Standard_Real aTol2 = aTol*aTol; + Standard_Real aTol2 = thePickArgs.Tolerance() * thePickArgs.Tolerance(); Standard_Integer aSize = mypolyg.Size(), anIndex; gp_XY CDG; for(anIndex=0;anIndexaTol) isplane2d=Standard_False; + if(isplane2d && Abs(valtst) > thePickArgs.Tolerance()) isplane2d=Standard_False; } if (isplane2d) { - return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), + thePickArgs.DepthMin(), + thePickArgs.DepthMax()); + + return !thePickArgs.IsClipped (theMatchDepth); } //otherwise it is checked if the point is in the face... TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize); Points2D(aArrayOf2dPnt); - CSLib_Class2d TheInOutTool(aArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax); - Standard_Integer TheStat = TheInOutTool.SiDans(gp_Pnt2d(X,Y)); + CSLib_Class2d TheInOutTool (aArrayOf2dPnt, + thePickArgs.Tolerance(), + thePickArgs.Tolerance(), + Xmin, Ymin, Xmax, Ymax); + Standard_Integer TheStat = TheInOutTool.SiDans (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y())); Standard_Boolean res(Standard_False); switch(TheStat) @@ -154,7 +145,11 @@ Matches(const Standard_Real X, } if (res) { - return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), + thePickArgs.DepthMin(), + thePickArgs.DepthMax()); + + return !thePickArgs.IsClipped (theMatchDepth); } return Standard_False; } @@ -232,25 +227,34 @@ void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean Ful //purpose : //======================================================================= -Standard_Real Select3D_SensitiveFace::ComputeDepth(const gp_Lin& EyeLine) const +Standard_Real Select3D_SensitiveFace::ComputeDepth (const gp_Lin& thePickLine, + const Standard_Real theDepthMin, + const Standard_Real theDepthMax) const { Standard_Real aDepth = Precision::Infinite(); - - Standard_Real aDepthMin = !mylastprj.IsNull() ? mylastprj->DepthMin() : -Precision::Infinite(); - Standard_Real aDepthMax = !mylastprj.IsNull() ? mylastprj->DepthMax() : Precision::Infinite(); - Standard_Real aDepthTest; + Standard_Real aPointDepth; for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex) { - aDepthTest = ElCLib::Parameter (EyeLine, mypolyg.Pnt(anIndex)); - if (aDepthTest < aDepth && (aDepthTest > aDepthMin) && (aDepthTest < aDepthMax)) + aPointDepth = ElCLib::Parameter (thePickLine, mypolyg.Pnt(anIndex)); + if (aPointDepth < aDepth && (aPointDepth > theDepthMin) && (aPointDepth < theDepthMax)) { - aDepth = aDepthTest; + aDepth = aPointDepth; } } return aDepth; } +//======================================================================= +//function : ComputeDepth +//purpose : +//======================================================================= + +void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const +{ + // this method is obsolete. +} + //======================================================================= //function : GetConnected //purpose : diff --git a/src/Select3D/Select3D_SensitiveGroup.cdl b/src/Select3D/Select3D_SensitiveGroup.cdl index 78689a73ef..bbe7a88a88 100755 --- a/src/Select3D/Select3D_SensitiveGroup.cdl +++ b/src/Select3D/Select3D_SensitiveGroup.cdl @@ -38,6 +38,7 @@ uses SensitiveEntity from Select3D, ListOfSensitive from Select3D, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt2d from TColgp, Box2d from Bnd, Location from TopLoc @@ -115,15 +116,14 @@ is ResetLocation(me:mutable) is redefined static; ---Purpose: propagation of location on all the sensitive inside... - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -138,14 +138,6 @@ is returns Boolean is redefined virtual; ---Level: Public - - - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; - ---Purpose: returns the depth of the touched entity - - - SetLastPrj(me:mutable;aPrj:Projector from Select3D) is redefined virtual; Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static; ---Purpose: Sets the owner for all entities in group @@ -160,8 +152,5 @@ is fields myList : ListOfSensitive from Select3D; myMustMatchAll : Boolean from Standard; - myLastRank : Integer from Standard; - myLastTol : ShortReal from Standard; - myX,myY : ShortReal from Standard; end SensitiveGroup; diff --git a/src/Select3D/Select3D_SensitiveGroup.cxx b/src/Select3D/Select3D_SensitiveGroup.cxx index 554afffbe7..62792e8c38 100755 --- a/src/Select3D/Select3D_SensitiveGroup.cxx +++ b/src/Select3D/Select3D_SensitiveGroup.cxx @@ -31,10 +31,7 @@ Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId, const Standard_Boolean MatchAll): Select3D_SensitiveEntity(OwnerId), -myMustMatchAll(MatchAll), -myLastRank(0), -myX(0.), -myY(0.) +myMustMatchAll(MatchAll) { } @@ -47,10 +44,7 @@ Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_Entit Select3D_ListOfSensitive& TheList, const Standard_Boolean MatchAll): Select3D_SensitiveEntity(OwnerId), -myMustMatchAll(MatchAll), -myLastRank(0), -myX(0.), -myY(0.) +myMustMatchAll(MatchAll) { myList.Append(TheList); } @@ -124,8 +118,6 @@ void Select3D_SensitiveGroup::Clear() void Select3D_SensitiveGroup::Project(const Handle(Select3D_Projector)& aProjector) { - Select3D_SensitiveEntity::Project(aProjector); // to set the field last proj... - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) { It.Value()->Project(aProjector); @@ -215,28 +207,34 @@ void Select3D_SensitiveGroup::ResetLocation() //purpose : //======================================================================= -Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitiveGroup::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { - myLastRank = 0; - myLastTol = (Standard_ShortReal)aTol; - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){ - myLastRank++; - if (It.Value()->Matches (X, Y, aTol, DMin)) + theMatchDMin = RealLast(); + theMatchDepth = RealLast(); + Standard_Real aChildDMin, aChildDepth; + Standard_Boolean isMatched = Standard_False; + + Select3D_ListIteratorOfListOfSensitive anIt (myList); + for (; anIt.More(); anIt.Next()) + { + Handle(SelectBasics_SensitiveEntity)& aChild = anIt.Value(); + if (!aChild->Matches (thePickArgs, aChildDMin, aChildDepth)) { - myX = (Standard_ShortReal)X; - myY = (Standard_ShortReal)Y; - myLastTol = (Standard_ShortReal)aTol; - // compute and validate the depth (will call ::ComputeDepth()) - return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin); + continue; } + + if (!isMatched) + { + theMatchDMin = aChildDMin; + isMatched = Standard_True; + } + + theMatchDepth = Min (aChildDepth, theMatchDepth); } - // no match - myLastRank = 0; - SetLastDepth (ShortRealLast()); - return Standard_False; + + return isMatched; } //======================================================================= @@ -301,37 +299,6 @@ Matches (const TColgp_Array1OfPnt2d& aPoly, return result; } -//======================================================================= -//function : ComputeDepth -//purpose : to optimise, the minimum depth for -// entities that answer YES to Matches(X,Y,...) is taken -// the test is started from mylastRank... -//======================================================================= -Standard_Real Select3D_SensitiveGroup::ComputeDepth(const gp_Lin& EyeLine) const -{ - Standard_Integer currank = 0; - Standard_Real DMin, thedepth (Precision::Infinite()); - for (Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - { - currank++; - if (currank >= myLastRank) - { - // this recomputes and validates the depth for the entity - if (It.Value()->Matches (myX, myY, myLastTol, DMin)) - { - It.Value()->ComputeDepth (EyeLine); - if (It.Value()->Depth() < thedepth) - { - // search for topmost entity - thedepth = It.Value()->Depth(); - //myLastRank = currank; // can not do this here... - } - } - } - } - return thedepth; -} - //======================================================================= //function : MaxBoxes //purpose : @@ -346,18 +313,6 @@ Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const return nbboxes; } -//======================================================================= -//function : SetLastPrj -//purpose : -//======================================================================= - -void Select3D_SensitiveGroup::SetLastPrj(const Handle(Select3D_Projector)& Prj) -{ - Select3D_SensitiveEntity::SetLastPrj(Prj); - for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) - It.Value()->SetLastPrj(Prj); -} - //======================================================================= //function : Set //purpose : diff --git a/src/Select3D/Select3D_SensitivePoint.cdl b/src/Select3D/Select3D_SensitivePoint.cdl index 33c7bcdeda..28474815d7 100755 --- a/src/Select3D/Select3D_SensitivePoint.cdl +++ b/src/Select3D/Select3D_SensitivePoint.cdl @@ -32,6 +32,7 @@ uses Lin from gp, EntityOwner from SelectBasics, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Location from TopLoc, Box2d from Bnd, Array1OfPnt2d from TColgp, @@ -62,16 +63,15 @@ is GetConnected(me:mutable;aLocation: Location from TopLoc) returns SensitiveEntity from Select3D is redefined static; - - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is redefined static; - ---Level: Public - ---Purpose: returns true if the X,Y position matches the point - -- else gives the distance between them. + + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -90,7 +90,7 @@ is ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; + returns Real from Standard; Point(me) returns Pnt from gp; diff --git a/src/Select3D/Select3D_SensitivePoint.cxx b/src/Select3D/Select3D_SensitivePoint.cxx index ae5d5c31d3..7b600eeaca 100755 --- a/src/Select3D/Select3D_SensitivePoint.cxx +++ b/src/Select3D/Select3D_SensitivePoint.cxx @@ -50,7 +50,6 @@ Select3D_SensitiveEntity(anOwner) void Select3D_SensitivePoint ::Project (const Handle(Select3D_Projector)& aProj) { - Select3D_SensitiveEntity::Project(aProj); // to set the field last proj... gp_Pnt2d aPoint2d; if(!HasLocation()) aProj->Project(mypoint, aPoint2d); @@ -80,19 +79,26 @@ void Select3D_SensitivePoint // Purpose : //================================================== -Standard_Boolean Select3D_SensitivePoint -::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitivePoint::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { - DMin = gp_Pnt2d(X,Y).Distance(myprojpt); - if(DMin<=aTol*SensitivityFactor()) + // check coordinate matching + Standard_Real aDist = gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()).Distance (myprojpt); + if (aDist > thePickArgs.Tolerance() * SensitivityFactor()) { - // compute and validate the depth (::Depth()) along the eyeline - return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); + return Standard_False; } - return Standard_False; + + Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine()); + if (thePickArgs.IsClipped (aDepth)) + { + return Standard_False; + } + + theMatchDMin = aDist; + theMatchDepth = aDepth; + return Standard_True; } //================================================== diff --git a/src/Select3D/Select3D_SensitivePoly.cxx b/src/Select3D/Select3D_SensitivePoly.cxx index 4c440e462b..ffbfc6e333 100755 --- a/src/Select3D/Select3D_SensitivePoly.cxx +++ b/src/Select3D/Select3D_SensitivePoly.cxx @@ -74,7 +74,6 @@ mypolyg(NbPoints) void Select3D_SensitivePoly::Project(const Handle(Select3D_Projector)& aProj) { - Select3D_SensitiveEntity:: Project (aProj); // to set the field last proj... mybox2d.SetVoid(); Standard_Boolean hasloc = HasLocation(); diff --git a/src/Select3D/Select3D_SensitiveSegment.cdl b/src/Select3D/Select3D_SensitiveSegment.cdl index 34b1948d8c..ec8af008ba 100755 --- a/src/Select3D/Select3D_SensitiveSegment.cdl +++ b/src/Select3D/Select3D_SensitiveSegment.cdl @@ -38,6 +38,7 @@ uses Lin from gp, EntityOwner from SelectBasics, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt2d from TColgp, Box2d from Bnd, Location from TopLoc, @@ -112,16 +113,15 @@ is GetConnected(me:mutable;aLocation: Location from TopLoc) returns SensitiveEntity from Select3D is redefined static; - - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm + + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -139,7 +139,7 @@ is ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; + returns Real from Standard; MaxBoxes(me) returns Integer is redefined static; ---Level: Public diff --git a/src/Select3D/Select3D_SensitiveSegment.cxx b/src/Select3D/Select3D_SensitiveSegment.cxx index d176dbef13..1476afc4a7 100755 --- a/src/Select3D/Select3D_SensitiveSegment.cxx +++ b/src/Select3D/Select3D_SensitiveSegment.cxx @@ -62,7 +62,6 @@ mymaxrect(MaxRect) void Select3D_SensitiveSegment ::Project(const Handle(Select3D_Projector)& aProj) { - Select3D_SensitiveEntity::Project(aProj); // to set the field last proj... gp_Pnt2d aPoint2dStart; gp_Pnt2d aPoint2dEnd; @@ -137,17 +136,24 @@ void Select3D_SensitiveSegment // Purpose : //===================================================== -Standard_Boolean Select3D_SensitiveSegment -::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitiveSegment::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { - gp_Pnt2d aPStart(myprojstart.x,myprojstart.y); - gp_Pnt2d aPEnd(myprojend.x,myprojend.y); - if ( ! SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd, X, Y, aTol, DMin) ) + gp_Pnt2d aPStart (myprojstart.x,myprojstart.y); + gp_Pnt2d aPEnd (myprojend.x,myprojend.y); + if (!SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd, + thePickArgs.X(), + thePickArgs.Y(), + thePickArgs.Tolerance(), + theMatchDMin)) + { return Standard_False; - return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin); // compute and validate depth + } + + theMatchDepth = ComputeDepth (thePickArgs.PickLine()); + + return !thePickArgs.IsClipped (theMatchDepth); } //===================================================== diff --git a/src/Select3D/Select3D_SensitiveTriangle.cdl b/src/Select3D/Select3D_SensitiveTriangle.cdl index 40f940c134..859b8f4359 100755 --- a/src/Select3D/Select3D_SensitiveTriangle.cdl +++ b/src/Select3D/Select3D_SensitiveTriangle.cdl @@ -33,6 +33,7 @@ uses Projector from Select3D, Lin from gp, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt2d from TColgp, Box2d from Bnd, XY from gp, @@ -54,12 +55,14 @@ is ---Purpose: Constructs a sensitive triangle object defined by the -- owner OwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity. - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is redefined virtual; + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) + returns Boolean is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -78,7 +81,7 @@ is ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; + returns Real from Standard; Points3D(me; P1,P2,P3 : out Pnt from gp) ; diff --git a/src/Select3D/Select3D_SensitiveTriangle.cxx b/src/Select3D/Select3D_SensitiveTriangle.cxx index b073b5c506..022d1745fe 100755 --- a/src/Select3D/Select3D_SensitiveTriangle.cxx +++ b/src/Select3D/Select3D_SensitiveTriangle.cxx @@ -79,28 +79,37 @@ mytype (aType) // Purpose : //================================================== -Standard_Boolean Select3D_SensitiveTriangle:: -Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) +Standard_Boolean Select3D_SensitiveTriangle::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) { - Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); - if(Bnd_Box2d(mybox2d).IsOut(gp_Pnt2d(X,Y))) return Standard_False; + Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine()); + if (thePickArgs.IsClipped (aDepth)) + { + return Standard_False; + } + + theMatchDepth = aDepth; + + if (Bnd_Box2d (mybox2d).IsOut (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()))) + { + return Standard_False; + } Standard_Integer Res; switch (mytype) { case Select3D_TOS_BOUNDARY: - Res = Status(X,Y,aTol,DMin); + Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin); return Res== 1; break; case Select3D_TOS_INTERIOR: - Res = Status(X,Y,aTol,DMin); + Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin); return (Res==0 || Res == 1); default: break; } + return Standard_True; } diff --git a/src/Select3D/Select3D_SensitiveTriangulation.cdl b/src/Select3D/Select3D_SensitiveTriangulation.cdl index b53e2c2453..fcc7c60519 100755 --- a/src/Select3D/Select3D_SensitiveTriangulation.cdl +++ b/src/Select3D/Select3D_SensitiveTriangulation.cdl @@ -31,6 +31,7 @@ uses Lin from gp, Trsf from gp, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt from TColgp, Array1OfPnt2d from TColgp, HArray1OfInteger from TColStd, @@ -83,12 +84,15 @@ is GetConnected(me:mutable;aLocation: Location from TopLoc) returns SensitiveEntity from Select3D is redefined static; - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) returns Boolean is redefined virtual; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -104,12 +108,16 @@ is returns Boolean is redefined virtual; ---Level: Public - - - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; - ---Purpose: give the depht of the last detected triangle - -- (center of gravity) + + ComputeDepth (me; + thePickLine : Lin from gp; + theTriangle : Integer from Standard) + returns Real from Standard; + ---Level: Public + ---Purpose: Compute precise depth of detected triangle. + -- @param thePickLine [in] the picking line. + -- @param theTriangle [in] the index of detected triangle. + -- @return depth on the picking line. DetectedTriangle(me) returns Integer from Standard; ---Purpose: Returns the detected three nodes P1, P2, P3 constituting a triangle. diff --git a/src/Select3D/Select3D_SensitiveTriangulation.cxx b/src/Select3D/Select3D_SensitiveTriangulation.cxx index 84871f2eb2..526388489e 100755 --- a/src/Select3D/Select3D_SensitiveTriangulation.cxx +++ b/src/Select3D/Select3D_SensitiveTriangulation.cxx @@ -207,8 +207,6 @@ myDetectedTr(-1) void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj) { - Select3D_SensitiveEntity::Project(aPrj); // to set the field last proj... - mybox2d.SetVoid(); const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); @@ -241,27 +239,25 @@ void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes) //function : Matches //purpose : //======================================================================= -Standard_Boolean Select3D_SensitiveTriangulation:: -Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) -{ - // get view direction (necessary for calculation of depth) from field mylastprj of the base class - if (mylastprj.IsNull()) - return Standard_False; - DMin = Precision::Infinite(); - gp_XY BidPoint(X,Y); +Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) +{ + theMatchDMin = Precision::Infinite(); + gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y()); myDetectedTr = -1; const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); // it is checked if we are inside the triangle 2d. if(myIntFlag) { - gp_Lin EyeLine = mylastprj->Shoot(X,Y); - if ( myTrsf.Form()!=gp_Identity ) - EyeLine.Transform (myTrsf.Inverted()); + gp_Lin aPickingLine = thePickArgs.PickLine(); + + if (myTrsf.Form() != gp_Identity) + { + aPickingLine.Transform (myTrsf.Inverted()); + } Standard_Real aMinDepth = Precision::Infinite(); const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); @@ -274,24 +270,22 @@ Matches(const Standard_Real X, const gp_XY& aPnt2d3 = myNodes2d(n3).XY(); gp_XY aUV; Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV); - if ( aDistSquare > aTol * aTol ) + if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance()) continue; - // compute depth on this triangle - Standard_Real aDepth1 = ElCLib::Parameter (EyeLine, Nodes(n1)); - Standard_Real aDepth2 = ElCLib::Parameter (EyeLine, Nodes(n2)); - Standard_Real aDepth3 = ElCLib::Parameter (EyeLine, Nodes(n3)); + // get interpolated depth of the triangle nodes + Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1)); + Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2)); + Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3)); Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) + aUV.Y() * (aDepth3 - aDepth1); - // take triangle with lowest depth and within defined depth interval - if (aDepth < aMinDepth && - aDepth > mylastprj->DepthMin() && - aDepth < mylastprj->DepthMax()) + // accept triangle with lowest depth and within defined depth interval + if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth)) { aMinDepth = aDepth; myDetectedTr = itr; - DMin = Sqrt (aDistSquare); + theMatchDMin = Sqrt (aDistSquare); } } } @@ -312,7 +306,7 @@ Matches(const Standard_Real X, Node2 = FreeE(ifri+1); if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(), myNodes2d(Node2).XY(), - BidPoint, aTol, DMin) ) + BidPoint, thePickArgs.Tolerance(), theMatchDMin)) { for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++) { @@ -330,10 +324,13 @@ Matches(const Standard_Real X, if ( myDetectedTr <= 0 ) return Standard_False; - // compute and validate the depth (::Depth()) along the eyeline - return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); -} + // get precise depth for the detected triangle + theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr); + // this test should not fail if the topmost triangle is taken from the + // first if-case block (for other cases this test make sense?) + return !thePickArgs.IsClipped (theMatchDepth); +} //======================================================================= //function : Matches @@ -509,86 +506,117 @@ void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Bo //purpose : //======================================================================= -Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& EyeLine) const +Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine, + const Standard_Integer theTriangle) const { - if(myDetectedTr==-1) return Precision::Infinite(); // currently not implemented... + if (theTriangle == -1) + { + return Precision::Infinite(); // currently not implemented... + } + const Poly_Array1OfTriangle& triangles = myTriangul->Triangles(); const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes(); Standard_Integer n1,n2,n3; - triangles(myDetectedTr).Get(n1,n2,n3); + triangles (theTriangle).Get (n1,n2,n3); gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)}; - if(myTrsf.Form()!=gp_Identity) + if (myTrsf.Form() != gp_Identity) { - for(Standard_Integer i =0;i<=2;i++) + for (Standard_Integer i =0; i<=2; i++) { - P[i].Transform(myTrsf); + P[i].Transform (myTrsf); } } // formula calculate the parameter of the point on the intersection // t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir) - Standard_Real prof(Precision::Infinite()); - gp_Pnt Oye = EyeLine.Location(); // origin of the target line eye/point... - gp_Dir Dir = EyeLine.Direction(); + Standard_Real prof (Precision::Infinite()); + gp_Pnt Oye = thePickLine.Location(); // origin of the target line eye/point... + gp_Dir Dir = thePickLine.Direction(); gp_Vec Vtr[3]; - for(Standard_Integer i=0;i<=2;i++) - Vtr[i] = gp_Vec(P[i%3],P[(i+1)%3]); + for (Standard_Integer i=0; i<=2; i++) + { + Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]); + } + Vtr[2] = -Vtr[2]; // remove singular cases immediately... - Standard_Integer SingularCase(-1); - if(Vtr[0].SquareMagnitude()<= Precision::Confusion()) + Standard_Integer SingularCase (-1); + if (Vtr[0].SquareMagnitude() <= Precision::Confusion()) + { SingularCase = 0; - if(Vtr[1].SquareMagnitude()<= Precision::Confusion()) + } + + if (Vtr[1].SquareMagnitude() <= Precision::Confusion()) + { SingularCase = (SingularCase == -1) ? 1 : 2; + } + #ifdef BUC60858 - if(Vtr[2].SquareMagnitude()<= Precision::Confusion()) + if (Vtr[2].SquareMagnitude() <= Precision::Confusion()) + { if( SingularCase < 0 ) SingularCase = 1; + } #endif // 3 pts mixed... - if(SingularCase ==2) + if (SingularCase ==2) { - prof= ElCLib::Parameter(EyeLine,P[0]); + prof = ElCLib::Parameter (thePickLine, P[0]); return prof; } - if(SingularCase!=0) + if (SingularCase!=0) + { Vtr[0].Normalize(); - if(SingularCase!=1 && - SingularCase!=2) + } + + if (SingularCase!=1 && SingularCase!=2) + { Vtr[2].Normalize(); - gp_Vec OPo(Oye,P[0]); + } + + gp_Vec OPo (Oye, P[0]); + // 2 points mixed... the intersection between the segment and the target line eye/point. - // - if(SingularCase!=-1) + if (SingularCase!=-1) { gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0]; gp_Vec Det = Dir^V; gp_Vec VSM = OPo^V; - if(Det.X()> Precision::Confusion()) - prof = VSM.X()/Det.X(); - else if (Det.Y()> Precision::Confusion()) - prof = VSM.Y()/Det.Y(); - else if(Det.Z()> Precision::Confusion()) - prof = VSM.Z()/Det.Z(); + + if (Det.X() > Precision::Confusion()) + { + prof = VSM.X() / Det.X(); + } + else if (Det.Y() > Precision::Confusion()) + { + prof = VSM.Y() / Det.Y(); + } + else if (Det.Z() > Precision::Confusion()) + { + prof = VSM.Z() / Det.Z(); + } } else { - Standard_Real val1 = OPo.DotCross(Vtr[0],Vtr[2]); - Standard_Real val2 = Dir.DotCross(Vtr[0],Vtr[2]); + Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]); + Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]); - if(Abs(val2)>Precision::Confusion()) - prof =val1/val2; + if (Abs (val2) > Precision::Confusion()) + { + prof = val1 / val2; + } } - if (prof==Precision::Infinite()) + + if (prof == Precision::Infinite()) { - prof= ElCLib::Parameter(EyeLine,P[0]); - prof = Min (prof, ElCLib::Parameter(EyeLine,P[1])); - prof = Min (prof, ElCLib::Parameter(EyeLine,P[2])); + prof= ElCLib::Parameter (thePickLine, P[0]); + prof = Min (prof, ElCLib::Parameter (thePickLine, P[1])); + prof = Min (prof, ElCLib::Parameter (thePickLine, P[2])); } return prof; diff --git a/src/Select3D/Select3D_SensitiveWire.cdl b/src/Select3D/Select3D_SensitiveWire.cdl index ffd1c907b5..116859dcf5 100755 --- a/src/Select3D/Select3D_SensitiveWire.cdl +++ b/src/Select3D/Select3D_SensitiveWire.cdl @@ -34,6 +34,7 @@ uses SensitiveEntity from Select3D, SensitiveEntitySequence from Select3D, ListOfBox2d from SelectBasics, + PickArgs from SelectBasics, Array1OfPnt2d from TColgp, Box2d from Bnd, Location from TopLoc @@ -76,15 +77,15 @@ is ResetLocation(me:mutable) is redefined static; ---Purpose: propagation of location on all the sensitive inside... - Matches(me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin, theMatchDepth : out Real from Standard) returns Boolean - is redefined static; - ---Level: Public - ---Purpose: projection of the sensitive primitive in order to - -- get 2D boxes for the Sort Algorithm + is redefined static; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking + -- detection area (close to the picking line). + -- For details please refer to base class declaration. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -101,10 +102,6 @@ is ---Level: Public - ComputeDepth(me;EyeLine: Lin from gp) - returns Real from Standard is redefined static; - ---Purpose: returns the depth of the touched entity - MaxBoxes(me) returns Integer is redefined static; ---Level: Public ---Purpose:returns @@ -114,9 +111,7 @@ is Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static; ---Purpose: Sets the owner for all entities in wire - - SetLastPrj(me:mutable;aPrj: Projector from Select3D) is redefined virtual; - + GetLastDetected(me) returns SensitiveEntity from Select3D is static; ---Purpose:returns diff --git a/src/Select3D/Select3D_SensitiveWire.cxx b/src/Select3D/Select3D_SensitiveWire.cxx index 4131679d39..3554019f6a 100755 --- a/src/Select3D/Select3D_SensitiveWire.cxx +++ b/src/Select3D/Select3D_SensitiveWire.cxx @@ -104,12 +104,12 @@ void Select3D_SensitiveWire::ResetLocation() // Function : Project // Purpose : //===================================================== -void Select3D_SensitiveWire -::Project(const Handle(Select3D_Projector)& aProj) +void Select3D_SensitiveWire::Project(const Handle(Select3D_Projector)& aProj) { - for(Standard_Integer i=1; i<=mysensitive.Length(); i++) - mysensitive(i)->Project(aProj); - Select3D_SensitiveEntity::Project(aProj); + for (Standard_Integer aSensIt = 1; aSensIt <= mysensitive.Length(); aSensIt++) + { + mysensitive (aSensIt)->Project (aProj); + } } //===================================================== @@ -136,33 +136,37 @@ void Select3D_SensitiveWire // Function : Matches // Purpose : //===================================================== -Standard_Boolean Select3D_SensitiveWire -::Matches(const Standard_Real X, - const Standard_Real Y, - const Standard_Real aTol, - Standard_Real& DMin) -{ - Standard_Integer i; - Standard_Real Dcur; - DMin = Precision::Infinite(); - Standard_Boolean IsTouched = Standard_False; - for (i=1; i<=mysensitive.Length(); i++) - { - if (mysensitive.Value(i)->Matches(X,Y,aTol,Dcur)) - { - IsTouched = Standard_True; - if(Dcur<=DMin) - { - myDetectedIndex = i; - DMin = Dcur; - } - } - } - if ( ! IsTouched ) - return Standard_False; - // compute and validate the depth (::Depth()) along the eyeline - return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin); +Standard_Boolean Select3D_SensitiveWire::Matches (const SelectBasics_PickArgs& thePickArgs, + Standard_Real& theMatchDMin, + Standard_Real& theMatchDepth) +{ + theMatchDMin = RealLast(); + theMatchDepth = RealLast(); + Standard_Real aSegDMin, aSegDepth; + Standard_Boolean isMatched = Standard_False; + myDetectedIndex = -1; + + for (Standard_Integer aSegIt = 1; aSegIt <= mysensitive.Length(); aSegIt++) + { + const Handle(SelectBasics_SensitiveEntity)& aSeg = mysensitive.Value (aSegIt); + if (!aSeg->Matches (thePickArgs, aSegDMin, aSegDepth)) + { + continue; + } + + isMatched = Standard_True; + if (aSegDMin > theMatchDMin) + { + continue; + } + + myDetectedIndex = aSegIt; + theMatchDMin = aSegDMin; + theMatchDepth = aSegDepth; + } + + return isMatched; } //===================================================== @@ -256,34 +260,6 @@ void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean Ful } -//======================================================================= -//function : ComputeDepth -//purpose : -//======================================================================= - -Standard_Real Select3D_SensitiveWire::ComputeDepth(const gp_Lin& EyeLine) const -{ - - if(myDetectedIndex==-1) - // should be never called... - return Precision::Infinite(); - return mysensitive(myDetectedIndex)->ComputeDepth(EyeLine); - -} - -//======================================================================= -//function : SetLastPrj -//purpose : -//======================================================================= - -void Select3D_SensitiveWire::SetLastPrj(const Handle(Select3D_Projector)& Prj) -{ - Select3D_SensitiveEntity::SetLastPrj(Prj); - for(Standard_Integer i=1;i<=mysensitive.Length();i++) - mysensitive(i)->SetLastPrj(Prj); - -} - //======================================================================= //function : GetEdges //purpose : returns the sensitive edges stored in this wire diff --git a/src/SelectBasics/FILES b/src/SelectBasics/FILES new file mode 100644 index 0000000000..3649dd9f50 --- /dev/null +++ b/src/SelectBasics/FILES @@ -0,0 +1 @@ +SelectBasics_PickArgs.hxx \ No newline at end of file diff --git a/src/SelectBasics/SelectBasics.cdl b/src/SelectBasics/SelectBasics.cdl index fb6e855d8a..d040c3f7d1 100755 --- a/src/SelectBasics/SelectBasics.cdl +++ b/src/SelectBasics/SelectBasics.cdl @@ -69,6 +69,9 @@ is class ListOfSensitive instantiates List from TCollection (SensitiveEntity); + imported PickArgs; + ---Purpose: Structure to provide all-in-one information on picking arguments + -- for "Matches" method of SelectBasics_SensitiveEntity. MaxOwnerPriority returns Integer; diff --git a/src/SelectBasics/SelectBasics_PickArgs.hxx b/src/SelectBasics/SelectBasics_PickArgs.hxx new file mode 100644 index 0000000000..7dd4e52d8f --- /dev/null +++ b/src/SelectBasics/SelectBasics_PickArgs.hxx @@ -0,0 +1,79 @@ +// Created on: 2013-09-04 +// Created by: Anton POLETAEV +// Copyright (c) 2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 65 (the "License") You may not use the content of this file +// except in compliance with the License Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file +// +// The Initial Developer of the Original Code is Open CASCADE SAS, having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement Please see the License for the specific terms +// and conditions governing the rights and limitations under the License + +#ifndef _SelectBasics_PickArgs_HeaderFile +#define _SelectBasics_PickArgs_HeaderFile + +#include +#include + +//! Structure to provide all-in-one information on picking arguments +//! for "Matches" method of SelectBasics_SensitiveEntity. +struct SelectBasics_PickArgs +{ +public: + + //! Constructor. + //! @param theX mouse picking coordinate on x-axis of selection coord space. + //! @param theY mouse picking coordinate on y-axis of selection coord space. + //! @param theTolerance x, y coordinate tolerance. + //! @param theDepthMin minimum picking depth in selection coord space. + //! @param theDepthMax maximum picking depth in selection coord space. + //! @param thePickingLine line going through picking point. + SelectBasics_PickArgs (const Standard_Real theX, + const Standard_Real theY, + const Standard_Real theTolerance, + const Standard_Real theDepthMin, + const Standard_Real theDepthMax, + const gp_Lin& thePickingLine) + : myX (theX), myY (theY), myTolerance (theTolerance), + myDepthMin (theDepthMin), myDepthMax (theDepthMax), + myPickingLine (thePickingLine) {} + +public: + + inline Standard_Real X() const { return myX; } + + inline Standard_Real Y() const { return myY; } + + inline Standard_Real Tolerance() const { return myTolerance; } + + inline Standard_Real DepthMin() const { return myDepthMin; } + + inline Standard_Real DepthMax() const { return myDepthMax; } + + inline const gp_Lin& PickLine() const { return myPickingLine; } + + //! @return True if passed depth lies outside valid depth range. + inline Standard_Boolean IsClipped(const Standard_Real theDepth) const + { + return (theDepth <= myDepthMin || theDepth >= myDepthMax); + } + +private: + + Standard_Real myX; //!< mouse picking coordinate on x-axis of selection coord space. + Standard_Real myY; //!< mouse picking coordinate on y-axis of selection coord space. + Standard_Real myTolerance; //!< x, y coordinate tolerance + Standard_Real myDepthMin; //!< minimum picking depth in selection coord space. + Standard_Real myDepthMax; //!< maximum picking depth in selection coord space. + gp_Lin myPickingLine; //!< line going through picking point +}; + +#endif diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.cdl b/src/SelectBasics/SelectBasics_SensitiveEntity.cdl index 687efeca2c..2b234d3f0d 100755 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.cdl +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.cdl @@ -28,7 +28,8 @@ deferred class SensitiveEntity from SelectBasics inherits TShared from MMgt uses EntityOwner, ListOfBox2d, - Array1OfPnt2d from TColgp, + PickArgs, + Array1OfPnt2d from TColgp, Box2d from Bnd is @@ -52,21 +53,49 @@ is ---Purpose: to be implemented specifically by each type of -- sensitive primitive . -- - - Matches (me :mutable; - X,Y : Real from Standard; - aTol: Real from Standard; - DMin: out Real from Standard) - returns Boolean - is deferred; - ---Level: Public - ---Purpose: returns True if the object is very close to the - -- sensitive areas it gave to the selector... - -- returns the minimum distance found if no match; - -- - -- to be implemented specifically by each type of - -- sensitive primitive . - + + Matches (me : mutable; + thePickArgs : PickArgs from SelectBasics; + theMatchDMin : out Real from Standard; + theMatchDepth : out Real from Standard) returns Boolean is deferred; + ---Level: Public + ---Purpose: Checks whether the sensitive entity matches the picking detection + -- area (close to the picking line). This method takes into account depth + -- limits produced by abstract view: far/near planes, clippings. + -- Please port existing implementations of your picking detection, which + -- were done at Matches (X, Y, Tol, DMin) method to this one, introducing + -- the depth checks. Please note that the previous method is suppressed + -- and the virtual implementations are not used by OCC selection framework. + -- The porting procedure for simple sensitives (or if you are not interested + -- in implementing full scale depth checks) can be simplified to writing the + -- following code snippet: + -- @code + -- { // example code for porting descendants of Select3D_SensitiveEntity + -- + -- // invoke implementation of obsolete matches method (if implemented)... + -- if (!Matches (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin)) + -- return Standard_False; + -- + -- // invoke your implementation of computing depth (if implemented)... + -- Standard_Real aDetectDepth = ComputeDepth (thePickArgs.PickLine()); + -- + -- return !thePickArgs.IsClipped(aDetectDepth); + -- } + -- @endcode + -- @param thePickArgs [in] the picking arguments. + -- @param theMatchDMin [out] the minimum distance on xy plane from point + -- of picking to center of gravity of the detected sub-part of sensitive + -- entity or the whole sensitive (e.g. used for resolving selection of + -- coinciding circles, selection will be set to the one whose center is + -- closest to the picking point). + -- @param theMatchDepth [out] the minimum detected depth: depth of the + -- closest detected sub-part of sensitive entity (or the whole sensitive). + -- @return True if the sensitive matches the detection area. + -- This method is an entry point for picking detection framework. + -- The method is triggered when it is required to compose list of + -- detected sensitive entities. The sensitives are filtered out from + -- detection result if returned value is False. The passed entities are + -- then can be sorted by "theDetectDist", "theDetectDepth" parameters. Matches (me :mutable; XMin,YMin,XMax,YMax : Real from Standard; @@ -96,10 +125,6 @@ is ---Purpose: returns True if able to give 3D information -- (Depth,...). See Select3D - Depth(me) returns Real from Standard is virtual; - ---Level: Internal - ---Purpose: Sort Selected entities according to depth... - MaxBoxes(me) returns Integer is deferred; ---Purpose: returns the max number of boxes the entity is able to give -- at a time diff --git a/src/SelectBasics/SelectBasics_SensitiveEntity.cxx b/src/SelectBasics/SelectBasics_SensitiveEntity.cxx index 98e32beebd..3516f08b49 100755 --- a/src/SelectBasics/SelectBasics_SensitiveEntity.cxx +++ b/src/SelectBasics/SelectBasics_SensitiveEntity.cxx @@ -39,7 +39,3 @@ void SelectBasics_SensitiveEntity const Handle(SelectBasics_EntityOwner)& SelectBasics_SensitiveEntity ::OwnerId() const {return myOwnerId;} - -Standard_Real SelectBasics_SensitiveEntity::Depth() const -{return 0.0;} - diff --git a/src/SelectMgr/FILES b/src/SelectMgr/FILES index 15d6fff53d..0e75a62daa 100755 --- a/src/SelectMgr/FILES +++ b/src/SelectMgr/FILES @@ -1,2 +1,2 @@ SelectMgr_DataMapOfObjectOwners.hxx -SelectMgr_CompareResults.hxx +SelectMgr_CompareResults.hxx \ No newline at end of file diff --git a/src/SelectMgr/SelectMgr.cdl b/src/SelectMgr/SelectMgr.cdl index 30e4a1696a..57744a000f 100755 --- a/src/SelectMgr/SelectMgr.cdl +++ b/src/SelectMgr/SelectMgr.cdl @@ -179,7 +179,8 @@ uses SelectBasics, PrsMgr, Prs3d, - Graphic3d + Graphic3d, + gp is diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cdl b/src/SelectMgr/SelectMgr_ViewerSelector.cdl index 69e1054894..924445b958 100755 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cdl +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cdl @@ -76,9 +76,10 @@ uses SensitiveEntity from SelectBasics, SortAlgo from SelectBasics, EntityOwner from SelectMgr, - StateOfSelection from SelectMgr, - Array1OfPnt2d from TColgp - + StateOfSelection from SelectMgr, + Array1OfPnt2d from TColgp, + Lin from gp + is Initialize ; @@ -229,12 +230,12 @@ is ---C++: inline - Picked(me) returns any EntityOwner is static; + Picked(me) returns EntityOwner from SelectMgr is static; ---Level: Public ---Purpose: Returns the current selected entity detected by the selector; - OnePicked(me:mutable) returns any EntityOwner is static; + OnePicked(me:mutable) returns EntityOwner from SelectMgr is static; ---Purpose: Returns the picked element with the highest priority, -- and which is the closest to the last successful mouse position. @@ -350,6 +351,54 @@ is SetUpdateSortPossible( me: mutable; possible : Boolean from Standard ); IsUpdateSortPossible( me ) returns Boolean from Standard; + PickingLine (me; theX, theY : Real from Standard) + returns Lin from gp + is virtual protected; + ---Level: Internal + ---Purpose: Returns picking line along which the depth value should be + -- computed. Override this method to compute picking line by the same + -- which is used for projecting sensitive entities to selection space. + -- @param theX [in] the x picking coordinate. + -- @param theY [in] the y picking coordinate. + -- @return picking line. + + DepthClipping (me; theX, theY : Real from Standard; + theMin, theMax : out Real from Standard) + is virtual protected; + ---Level: Internal + ---Purpose: Returns global depth clipping limits applied to every sensitive. + -- Override this method to convert clippings defined by application into + -- selection space for mouse picking detection. + -- Default implementation returns infinite clip limits (no clipping). + -- @param theX [in] the x picking coordinate. + -- @param theY [in] the y picking coordinate. + -- @param theMin [out] the minimum depth. Default is RealFirst() + -- @param theMax [out] the maximum depth. Default is RealLast() + + DepthClipping (me; theX, theY : Real from Standard; + theOwner : EntityOwner from SelectMgr; + theMin, theMax : out Real from Standard) + is virtual protected; + ---Level: Internal + ---Purpose: Returns depth clipping limits applied to sensitives of + -- entity owner. Override this method to convert clippings defined by + -- application owners into selection space for mouse picking detection. + -- Default implementation returns infinite clip limits (no clipping). + -- @param theX [in] the x picking coordinate. + -- @param theY [in] the y picking coordinate. + -- @param theOwner [in] the sensitive owner. + -- @param theMin [out] the minimum depth. Default is RealFirst() + -- @param theMax [out] the maximum depth. Default is RealLast() + + HasDepthClipping (me; theOwner : EntityOwner from SelectMgr) + returns Boolean is virtual protected; + ---Level: Internal + ---Purpose: Returns True if the owner provides clipping by depth + -- for its sensitives. Override this method to tell the selector + -- to use the DepthClipping method for the owner. + -- Default implementation returns False for every owner. + -- @param theOwner [in] the onwer to check. + -- @return True if owner provides depth limits for sensitive clipping. fields diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index 289119b565..6eb88d7f7b 100755 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -32,14 +32,15 @@ #include #include #include +#include +#include #include #include -#include #include +#include #include #include #include -#include #include #include @@ -51,10 +52,34 @@ static Standard_Boolean SelectDebugModeOnVS() OSD_Environment selectdb("SELDEBUGMODE"); if ( selectdb.Value().IsEmpty() ) isDebugMode = 0; - } + } return ( isDebugMode != 0 ); } +namespace +{ + // container to store depth limits in collection map + struct SelectMgr_DepthRange + { + Standard_Real DepthMin; + Standard_Real DepthMax; + Standard_Boolean IsEmpty() const { return (DepthMin == DepthMax); } + + void Common (const SelectMgr_DepthRange& theOther) + { + if (theOther.DepthMin > DepthMax || theOther.DepthMax < DepthMin) + { + DepthMin = RealFirst(); + DepthMax = RealLast(); + return; + } + + DepthMin = Max (DepthMin, theOther.DepthMin); + DepthMax = Min (DepthMax, theOther.DepthMax); + } + }; +}; + //================================================== // Function: Initialize // Purpose : @@ -85,7 +110,7 @@ Activate (const Handle(SelectMgr_Selection)& aSelection, if (!myselections.IsBound(aSelection)) { myselections.Bind(aSelection,0); - } + } else if (myselections(aSelection)!=0) { myselections(aSelection)= 0; @@ -124,11 +149,11 @@ UpdateSort(); } //======================================================================= //function : Sleep -//purpose : +//purpose : //======================================================================= void SelectMgr_ViewerSelector::Sleep(const Handle(SelectMgr_SelectableObject)& SO) -{ +{ for(SO->Init();SO->More();SO->Next()){ if(myselections.IsBound(SO->CurrentSelection())){ @@ -243,7 +268,7 @@ void SelectMgr_ViewerSelector::UpdateSort() if(It.Value()== 0) { curEntity = It.Key(); for(curEntity->Init();curEntity->More();curEntity->Next()) - { + { static SelectBasics_ListOfBox2d BoxList; BoxList.Clear(); curEntity->Sensitive()->Areas(BoxList); @@ -395,7 +420,7 @@ void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly) if (toupdate) UpdateConversion(); if (tosort) UpdateSort(); if (myactivenb!=0){ - // the Bnd boxes are used for the first time + // the Bnd boxes are used for the first time Bnd_Box2d aBox; Standard_Integer NbPnt = aPoly.Length(); Standard_Integer i; @@ -411,66 +436,113 @@ void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly) //================================================== // Function: LoadResult -// Purpose : for the moment the size of the primitive +// Purpose : for the moment the size of the primitive // is not taken into account in the search criteriai... // The priority, the depth and the min. distance to CDG or Borders is taken... //================================================== -void SelectMgr_ViewerSelector:: -LoadResult() +void SelectMgr_ViewerSelector::LoadResult() { - // Handle(SelectMgr_EntityOwner) OWNR; - if(myselector.More()) + if (myselector.More()) { - // Standard_Boolean Found(Standard_False); - Standard_Real DMin; - Standard_Integer nument; - for(;myselector.More();myselector.Next()){ - nument = myselector.Value(); - const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument); - if (SE->Matches(lastx,lasty,mytolerance,DMin)) { - const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId(); + NCollection_DataMap aMapOfOwnerRanges; - if(!OWNR.IsNull()){ - Standard_Real TheDepth = SE->Depth(); - Standard_Integer Prior = OWNR->Priority(); + // collect information on depth clipping from implementations + gp_Lin aPickLine = PickingLine (lastx, lasty); + SelectMgr_DepthRange aViewDRange; + DepthClipping (lastx, lasty, aViewDRange.DepthMin, aViewDRange.DepthMax); - SelectMgr_SortCriterion SC(Prior,TheDepth,DMin,mytolerance,preferclosest); - if ( mystored.Contains(OWNR) ) + Standard_Real aDMin; + Standard_Real aDepthMin; + Standard_Integer aNument; + + if (!aViewDRange.IsEmpty()) + { + for (; myselector.More(); myselector.Next()) + { + aNument = myselector.Value(); + + const Handle(SelectBasics_SensitiveEntity)& SE = myentities (aNument); + const Handle(SelectMgr_EntityOwner)& anOwner = + Handle(SelectMgr_EntityOwner)::DownCast (SE->OwnerId()); + + // compute depth range for sensitives of entity owner + SelectMgr_DepthRange anEntityDRange (aViewDRange); + if (!anOwner.IsNull() && HasDepthClipping (anOwner) && !aMapOfOwnerRanges.Find (anOwner, anEntityDRange)) + { + // get depth range from implementation + SelectMgr_DepthRange aGetRange; + DepthClipping (lastx, lasty, anOwner, aGetRange.DepthMin, aGetRange.DepthMax); + + // concatenate and remember depth range for pefromance increase + anEntityDRange.Common (aGetRange); + aMapOfOwnerRanges.Bind (anOwner, anEntityDRange); + } + + if (anEntityDRange.IsEmpty()) + { + continue; + } + + SelectBasics_PickArgs aPickArgs (lastx, lasty, mytolerance, + anEntityDRange.DepthMin, + anEntityDRange.DepthMax, + aPickLine); + + if (SE->Matches (aPickArgs, aDMin, aDepthMin)) + { + if (!anOwner.IsNull()) { - SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey(OWNR); - if ( SC > Crit ) + Standard_Integer aPrior = anOwner->Priority(); + + SelectMgr_SortCriterion SC (aPrior, aDepthMin, aDMin, mytolerance, preferclosest); + if (mystored.Contains (anOwner)) { - Crit = SC; + SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey (anOwner); + if (SC > Crit) + { + Crit = SC; - // update previously recorded entity for this owner - for (int i=1; i <= myprim.Length(); i++) - if (myentities(myprim(i))->OwnerId() == OWNR) { - myprim.SetValue (i, nument); - break; + // update previously recorded entity for this owner + for (int i = 1; i <= myprim.Length(); i++) + { + if (myentities (myprim(i))->OwnerId() == anOwner) + { + myprim.SetValue (i, aNument); + break; + } } + } } - } - else - { - mystored.Add(OWNR,SC); + else + { + mystored.Add (anOwner, SC); - // record entity - myprim.Append(nument); + // record entity + myprim.Append (aNument); + } } } } } + SortResult(); } - if( SelectDebugModeOnVS() ){ + + if (SelectDebugModeOnVS()) + { cout<<"\tSelectMgr_VS:: Resultat du move"<Value(i)); - cout<<"\t"<Value(i)); + cout << "\t" << i << " - Prior" << Crit.Priority() + << " - prof :" << Crit.Depth() + << " - Dist. :" << Crit.MinDist() << endl; } } } + //================================================== // Function: LoadResult // Purpose : @@ -479,7 +551,7 @@ void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox) { mystored.Clear(); - // Handle(SelectMgr_EntityOwner) OWNR; + // Handle(SelectMgr_EntityOwner) OWNR; if(myselector.More()) { Standard_Real xmin,ymin,xmax,ymax; abox.Get(xmin,ymin,xmax,ymax); @@ -503,17 +575,17 @@ void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox) } // do not parse in case of selection by elastic rectangle (BUG ANALYST) - if(mystored.IsEmpty()) return; - if(myIndexes.IsNull()) - myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); - else if(mystored.Extent() !=myIndexes->Length()) - myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); + if(mystored.IsEmpty()) return; + if(myIndexes.IsNull()) + myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); + else if(mystored.Extent() !=myIndexes->Length()) + myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); - // to work faster... - TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); - for(Standard_Integer I=1;I<=mystored.Extent();I++) - thearr(I)=I; - } + // to work faster... + TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); + for(Standard_Integer I=1;I<=mystored.Extent();I++) + thearr(I)=I; + } } //================================================== // Function: LoadResult @@ -529,9 +601,9 @@ void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly) aBox.Update(aPoly(i).X(),aPoly(i).Y()); } Standard_Integer NB=0; - // Handle(SelectMgr_EntityOwner) OWNR; + // Handle(SelectMgr_EntityOwner) OWNR; if(myselector.More()) - { + { Standard_Integer nument; for(;myselector.More();myselector.Next()){ @@ -551,16 +623,16 @@ void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly) } } - if(mystored.IsEmpty()) return; - if(myIndexes.IsNull()) - myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); - else if(mystored.Extent() !=myIndexes->Length()) - myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); + if(mystored.IsEmpty()) return; + if(myIndexes.IsNull()) + myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); + else if(mystored.Extent() !=myIndexes->Length()) + myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); - // to work faster... - TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); - for(Standard_Integer I=1;I<=mystored.Extent();I++) - thearr(I)=I; + // to work faster... + TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); + for(Standard_Integer I=1;I<=mystored.Extent();I++) + thearr(I)=I; } } @@ -599,9 +671,9 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector //======================================================================= //function : More -//purpose : +//purpose : //======================================================================= -Standard_Boolean SelectMgr_ViewerSelector::More() +Standard_Boolean SelectMgr_ViewerSelector::More() { if(mystored.Extent()==0) return Standard_False; if(myCurRank==0) return Standard_False; @@ -633,7 +705,7 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector //======================================================================= //function : NbPicked -//purpose : +//purpose : //======================================================================= Standard_Integer SelectMgr_ViewerSelector::NbPicked() const @@ -642,12 +714,12 @@ Standard_Integer SelectMgr_ViewerSelector::NbPicked() const } //======================================================================= //function : Picked -//purpose : +//purpose : //======================================================================= Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const { - Handle(SelectMgr_EntityOwner) Own; + Handle(SelectMgr_EntityOwner) Own; if (aRank<1 || aRank>NbPicked()) return Own; Standard_Integer Indx = myIndexes->Value(aRank); @@ -659,7 +731,7 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_In } //======================================================================= //function : Primitive -//purpose : +//purpose : //======================================================================= Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive (const Standard_Integer /*Index*/) const @@ -674,7 +746,7 @@ Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive //================================================== void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast, Standard_Real& YLast) const -{ Xlast = lastx;YLast = lasty;} +{ Xlast = lastx;YLast = lasty;} @@ -711,7 +783,7 @@ Standard_Integer SelectMgr_ViewerSelector::NbBoxes() //================================================== // Function: Contains -// Purpose : +// Purpose : //================================================== Standard_Boolean SelectMgr_ViewerSelector:: Contains(const Handle(SelectMgr_SelectableObject)& anObject) const @@ -734,14 +806,14 @@ Contains(const Handle(SelectMgr_SelectableObject)& anObject) const Standard_Boolean SelectMgr_ViewerSelector:: Modes(const Handle(SelectMgr_SelectableObject)& SO, TColStd_ListOfInteger& TheActiveList, - const SelectMgr_StateOfSelection WantedState) const + const SelectMgr_StateOfSelection WantedState) const { Standard_Boolean Found= Standard_False; for(SO->Init();SO->More();SO->Next()){ if(myselections.IsBound(SO->CurrentSelection())){ if(WantedState==SelectMgr_SOS_Any) TheActiveList.Append(SO->CurrentSelection()->Mode()); - else if( myselections(SO->CurrentSelection())==WantedState) + else if( myselections(SO->CurrentSelection())==WantedState) TheActiveList.Append(SO->CurrentSelection()->Mode()); if(!Found) Found=Standard_True; @@ -757,8 +829,8 @@ IsActive(const Handle(SelectMgr_SelectableObject)& SO, { for(SO->Init();SO->More();SO->Next()){ if(aMode==SO->CurrentSelection()->Mode()){ - if(myselections.IsBound(SO->CurrentSelection()) && - myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated) + if(myselections.IsBound(SO->CurrentSelection()) && + myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated) return Standard_True; else return Standard_False; } @@ -784,10 +856,10 @@ IsInside(const Handle(SelectMgr_SelectableObject)& SO, //======================================================================= //function : Status -//purpose : +//purpose : //======================================================================= -SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const +SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const { if(!myselections.IsBound(aSel)) return SelectMgr_SOS_Unknown; //JR/Hp @@ -801,7 +873,7 @@ SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectM //======================================================================= //function : Dump -//purpose : +//purpose : //======================================================================= void SelectMgr_ViewerSelector::Dump(Standard_OStream& S) const @@ -828,10 +900,10 @@ Status(const Handle(SelectMgr_SelectableObject)& SO) const if(myselections.IsBound(SO->CurrentSelection())) { Found = Standard_True; - Status = Status + "Mode " + + Status = Status + "Mode " + TCollection_AsciiString(SO->CurrentSelection()->Mode()) + " present - " ; - if(myselections(SO->CurrentSelection())) + if(myselections(SO->CurrentSelection())) Status = Status + " Active \n\t"; else Status = Status + " Inactive \n\t"; @@ -844,15 +916,15 @@ Status(const Handle(SelectMgr_SelectableObject)& SO) const TCollection_AsciiString SelectMgr_ViewerSelector:: -Status () const +Status () const { - // sevsitive primitives present + // sevsitive primitives present //----------------------------- TCollection_AsciiString Status("\t\tSelector Status :\n\t"); // selections //----------- Standard_Integer NbActive =0,NbPrim=0; - Status = Status + "Number of already computed selections : " + + Status = Status + "Number of already computed selections : " + TCollection_AsciiString(myselections.Extent()); SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections); @@ -863,7 +935,7 @@ Status () const } } Status = Status + " - " + TCollection_AsciiString(NbActive) + " activated ones\n\t"; - Status = Status + "Number of active sensitive primitives : " + + Status = Status + "Number of active sensitive primitives : " + TCollection_AsciiString(NbPrim)+"\n\t"; Status = Status + "Real stored Pick Tolerance : " + TCollection_AsciiString(mytolerance) +"\n\t"; if(toupdate) { @@ -875,13 +947,13 @@ Status () const //======================================================================= //function : SortResult -//purpose : there is a certain number of entities ranged by criteria +//purpose : there is a certain number of entities ranged by criteria // (depth, size, priority, mouse distance from borders or // CDG of the detected primitive. Parsing : // maximum priorities . // then a reasonable compromise between depth and distance... // finally the ranges are stored in myindexes depending on the parsing. -// so, it is possible to only read +// so, it is possible to only read //======================================================================= void SelectMgr_ViewerSelector::SortResult() { @@ -946,7 +1018,7 @@ void SelectMgr_ViewerSelector::SortResult() //======================================================================= //function : -//purpose : +//purpose : //======================================================================= Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const { @@ -955,9 +1027,55 @@ Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const //======================================================================= //function : -//purpose : +//purpose : //======================================================================= void SelectMgr_ViewerSelector::SetUpdateSortPossible( const Standard_Boolean possible ) { myUpdateSortPossible = possible; } + +//======================================================================= +//function : PickingLine +//purpose : Stub +//======================================================================= +gp_Lin SelectMgr_ViewerSelector::PickingLine (const Standard_Real /*theX*/, + const Standard_Real /*theY*/) const +{ + return gp_Lin(); +} + +//======================================================================= +//function : DepthClipping +//purpose : Stub +//======================================================================= +void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/, + const Standard_Real /*theY*/, + Standard_Real& theMin, + Standard_Real& theMax) const +{ + theMin = RealFirst(); + theMax = RealLast(); +} + +//======================================================================= +//function : DepthClipping +//purpose : Stub +//======================================================================= +void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/, + const Standard_Real /*theY*/, + const Handle(SelectMgr_EntityOwner)& /*theOwner*/, + Standard_Real& theMin, + Standard_Real& theMax) const +{ + theMin = RealFirst(); + theMax = RealLast(); +} + +//======================================================================= +//function : HasDepthClipping +//purpose : Stub +//======================================================================= +Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const +{ + return Standard_False; +} diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cdl b/src/StdSelect/StdSelect_ViewerSelector3d.cdl index 832ff86957..55c93f169d 100755 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cdl +++ b/src/StdSelect/StdSelect_ViewerSelector3d.cdl @@ -30,12 +30,15 @@ class ViewerSelector3d from StdSelect inherits ViewerSelector from SelectMgr uses View from V3d, Selection from SelectMgr, + EntityOwner from SelectMgr, Projector from Select3D, Group from Graphic3d, Structure from Graphic3d, + SetOfHClipPlane from Graphic3d, Array1OfReal from TColStd, Array1OfPnt2d from TColgp, - SensitivityMode from StdSelect + SensitivityMode from StdSelect, + Lin from gp is @@ -106,10 +109,6 @@ is ---Category: Internal Methods -- ----------------- - ReactivateProjector(me:mutable); - ---Level: Internal - ---Purpose: Puts back the address of the current projector in sensitive primitives... - UpdateProj(me :mutable; aView: View from V3d) returns Boolean is static private; ---Level: Internal @@ -153,9 +152,46 @@ is is static private; ---Level: Internal - + SetClipping (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is protected; + ---Level: Internal + ---Purpose: Set view clipping for the selector. + -- @param thePlanes [in] the view planes. + ComputeClipRange (me; thePlanes : SetOfHClipPlane from Graphic3d; + thePickLine : Lin from gp; + theDepthMin, theDepthMax : out Real from Standard) + is protected; + ---Level: Internal + ---Purpose: Computed depth boundaries for the passed set of clipping planes and picking line. + -- @param thePlanes [in] the planes. + -- @param thePickLine [in] the picking line. + -- @param theDepthMin [out] minimum depth limit. + -- @param theDepthMax [out] maximum depth limit. + PickingLine (me; theX, theY : Real from Standard) + returns Lin from gp + is redefined protected; + ---Level: Internal + ---Purpose: For more details please refer to base class. + + DepthClipping (me; theX, theY : Real from Standard; + theMin, theMax : out Real from Standard) + is redefined protected; + ---Level: Internal + ---Purpose: For more details please refer to base class. + + DepthClipping (me; theX, theY : Real from Standard; + theOwner : EntityOwner from SelectMgr; + theMin, theMax : out Real from Standard) + is redefined protected; + ---Level: Internal + ---Purpose: For more details please refer to base class. + + HasDepthClipping (me; theOwner : EntityOwner from SelectMgr) + returns Boolean is redefined protected; + ---Level: Internal + ---Purpose: For more details please refer to base class. + fields myprj : Projector from Select3D; @@ -174,8 +210,8 @@ fields myareagroup : Group from Graphic3d; mysensgroup : Group from Graphic3d; mystruct: Structure from Graphic3d; + myClipPlanes : SetOfHClipPlane from Graphic3d; - end ViewerSelector3d; diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cxx b/src/StdSelect/StdSelect_ViewerSelector3d.cxx index 87885ce2c5..1c88fce988 100755 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.cxx @@ -29,10 +29,12 @@ #include #include #include +#include #include -#include #include #include +#include +#include #include #include #include @@ -197,57 +199,13 @@ void StdSelect_ViewerSelector3d const Standard_Integer YPix, const Handle(V3d_View)& aView) { + SetClipping (aView->GetClipPlanes()); UpdateProj(aView); Standard_Real Xr3d,Yr3d,Zr3d; gp_Pnt2d P2d; aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d); myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d); - // compute depth limits if clipping plane(s) enabled - gp_Lin anEyeLine = myprj->Shoot (P2d.X(), P2d.Y()); - Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD; - Standard_Real aDepthFrom = ShortRealFirst(); - Standard_Real aDepthTo = ShortRealLast(); - for (aView->InitActivePlanes(); aView->MoreActivePlanes(); aView->NextActivePlanes()) - { - aView->ActivePlane()->Plane (aPlaneA, aPlaneB, aPlaneC, aPlaneD); - const gp_Dir& anEyeLineDir = anEyeLine.Direction(); - gp_Dir aPlaneNormal (aPlaneA, aPlaneB, aPlaneC); - - Standard_Real aDotProduct = anEyeLineDir.Dot (aPlaneNormal); - Standard_Real aDirection = -(aPlaneD + anEyeLine.Location().XYZ().Dot (aPlaneNormal.XYZ())); - if (Abs (aDotProduct) < Precision::Angular()) - { - // eyeline parallel to the clipping plane - if (aDirection > 0.0) - { - // invalidate the interval - aDepthTo = ShortRealFirst(); - aDepthFrom = ShortRealFirst(); - break; - } - // just ignore this plane - continue; - } - - // compute distance along the eyeline from eyeline location to intersection with clipping plane - Standard_Real aDepth = aDirection / aDotProduct; - - // reduce depth limits - if (aDotProduct < 0.0) - { - if (aDepth < aDepthTo) - { - aDepthTo = aDepth; - } - } - else if (aDepth > aDepthFrom) - { - aDepthFrom = aDepth; - } - } - myprj->DepthMinMax (aDepthFrom, aDepthTo); - InitSelect(P2d.X(),P2d.Y()); } @@ -1087,18 +1045,123 @@ void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selecti } //======================================================================= -//function : ReactivateProjector +//function : SetClipping //purpose : //======================================================================= -void StdSelect_ViewerSelector3d::ReactivateProjector() +void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SetOfHClipPlane& thePlanes) { - Handle(SelectBasics_SensitiveEntity) BS; - for (SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive it (myentities); it.More(); it.Next()) + myClipPlanes = thePlanes; +} + +//======================================================================= +//function : ComputeClipRange +//purpose : +//======================================================================= +void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SetOfHClipPlane& thePlanes, + const gp_Lin& thePickLine, + Standard_Real& theDepthMin, + Standard_Real& theDepthMax) const +{ + theDepthMin = RealFirst(); + theDepthMax = RealLast(); + Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD; + + Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes); + for (; aPlaneIt.More(); aPlaneIt.Next()) { - BS = it.Value(); - if (BS->Is3D()) + const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value(); + if (!aClipPlane->IsOn()) + continue; + + gp_Pln aGeomPlane = aClipPlane->ToPlane(); + + aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD); + + const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction(); + const gp_Dir& aPickDir = thePickLine.Direction(); + const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ(); + const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ(); + + Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir); + Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD); + + // check whether the pick line is parallel to clip plane + if (Abs (aDotProduct) < Precision::Angular()) { - (*((Handle(Select3D_SensitiveEntity)*) &BS))->SetLastPrj (myprj); + if (aDistance > 0.0) + { + // line lies above the plane, thus no selection is possible + theDepthMin = 0.0; + theDepthMax = 0.0; + return; + } + + // line lies below the plane and is not clipped, skip + continue; + } + + // compute distance to point of pick line intersection with the plane + Standard_Real aIntDist = aDistance / aDotProduct; + + // change depth limits for case of opposite and directed planes + if (aDotProduct < 0.0) + { + theDepthMax = Min (aIntDist, theDepthMax); + } + else if (aIntDist > theDepthMin) + { + theDepthMin = Max (aIntDist, theDepthMin); } } } + +//======================================================================= +//function : PickingLine +//purpose : +//======================================================================= +gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const +{ + return myprj->Shoot (theX, theY); +} + +//======================================================================= +//function : DepthClipping +//purpose : +//======================================================================= +void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX, + const Standard_Real theY, + Standard_Real& theDepthMin, + Standard_Real& theDepthMax) const +{ + return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax); +} + +//======================================================================= +//function : DepthClipping +//purpose : +//======================================================================= +void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX, + const Standard_Real theY, + const Handle(SelectMgr_EntityOwner)& theOwner, + Standard_Real& theDepthMin, + Standard_Real& theDepthMax) const +{ + return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(), + PickingLine (theX, theY), + theDepthMin, theDepthMax); +} + +//======================================================================= +//function : HasDepthClipping +//purpose : +//======================================================================= +Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const +{ + if (!theOwner->HasSelectable()) + { + return Standard_False; + } + + const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable(); + return (aSelectable->GetClipPlanes().Size() > 0); +} diff --git a/src/V3d/FILES b/src/V3d/FILES index e07ede2c76..4d211e0077 100755 --- a/src/V3d/FILES +++ b/src/V3d/FILES @@ -10,3 +10,5 @@ V3d_Viewer_3.cxx V3d_Viewer_4.cxx V3d_View_Print.cxx V3d_View_5.cxx +V3d_Plane.hxx +V3d_Plane.cxx \ No newline at end of file diff --git a/src/V3d/V3d.cdl b/src/V3d/V3d.cdl index f52e78b48b..5ff965ae82 100755 --- a/src/V3d/V3d.cdl +++ b/src/V3d/V3d.cdl @@ -213,9 +213,6 @@ is class SpotLight; ---Purpose: Services of spot light sources. - class Plane; - ---Pupose: Services of any kind of clipping plane. - --------------------------------- ---Category: Instantiated classes --------------------------------- diff --git a/src/V3d/V3d_Plane.cdl b/src/V3d/V3d_Plane.cdl deleted file mode 100755 index 30de00030b..0000000000 --- a/src/V3d/V3d_Plane.cdl +++ /dev/null @@ -1,131 +0,0 @@ --- Created on: 1992-01-17 --- Created by: GG --- Copyright (c) 1992-1999 Matra Datavision --- Copyright (c) 1999-2012 OPEN CASCADE SAS --- --- The content of this file is subject to the Open CASCADE Technology Public --- License Version 6.5 (the "License"). You may not use the content of this file --- except in compliance with the License. Please obtain a copy of the License --- at http://www.opencascade.org and read it completely before using this file. --- --- The Initial Developer of the Original Code is Open CASCADE S.A.S., having its --- main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. --- --- The Original Code and all software distributed under the License is --- distributed on an "AS IS" basis, without warranty of any kind, and the --- Initial Developer hereby disclaims all such warranties, including without --- limitation, any warranties of merchantability, fitness for a particular --- purpose or non-infringement. Please see the License for the specific terms --- and conditions governing the rights and limitations under the License. - --- Modified: GG 23/11/00 Add Display(),Erase(),IsDisplayed() methods - - -class Plane from V3d - -inherits - - TShared - ---Purpose: Defines the services of Plane type objects. Only - -- the creation and editing of the functions is dealt - -- with here. - -- Warning: The representation of the clipping plane must be - -- calculated by the application by means of Graphic3d. - -- Editing of this representation must be coherent with - -- respect to the position of the plane. - -uses - - View from V3d, - ClipPlane from Visual3d, - Structure from Graphic3d, - Parameter from Quantity, - Color from Quantity - - -raises - - BadValue from V3d - -is - - -- - -- The methods : - -- - - Create (A: Parameter = 0.0; - B: Parameter = 0.0; - C: Parameter = 1.0; - D: Parameter = 0.0 - ) returns mutable Plane - ---Level : Public - ---Purpose: Creates a clipping plane using the equation : - -- *X + *Y + *Z + = 0.0 - raises BadValue from V3d; - ---Purpose: Warning! raises BadValue from V3d - -- if the norm of the plane is NULL. - - -------------------------------------------------------- - ---Category: Methods to modify the Attributs of the Plane - -------------------------------------------------------- - - SetPlane( me : mutable; A,B,C,D : Parameter) - ---Level : Public - ---Purpose: Modifies the plane equation. - raises BadValue from V3d - ---Purpose: Warning! raises BadValue from V3d - -- if the norm of the plane is NULL. - -- If the norm of the plane is NULL. - is static; - - Display(me: mutable; aView: View from V3d; - aColor: Color from Quantity= Quantity_NOC_GRAY) - ---Level : Public - ---Purpose: Display the plane representation - -- in the choosen view. - is virtual; - - Erase(me: mutable) is static; - ---Level: Public - ---Purpose: Erase the plane representation. - - --------------------------------------------------- - ---Category: Inquire methods - --------------------------------------------------- - - Plane( me ; A,B,C,D : out Parameter ) is static; - ---Level : Public - ---Purpose: Returns the parameters of the plane . - - IsDisplayed( me ) returns Boolean from Standard is static; - ---Level : Public - ---Purpose: Returns TRUE when the plane representation is displayed - - ----------------------------------------- - ---Category: Private or Protected methods - ----------------------------------------- - - Plane( me) returns mutable ClipPlane from Visual3d is static private ; - ---Level : Internal - ---Purpose: Returns the associated plane from Visual3d. - - Update( me : mutable ) is static private; - ---Level : Internal - ---Purpose: Updates the the plane representation. - - -fields - - MyPlane: ClipPlane from Visual3d ; - MyGraphicStructure: Structure from Graphic3d is protected; - -friends - - SetPlaneOn from class View from V3d ( me : mutable ), - SetPlaneOn from class View from V3d - ( me : mutable ; Plane : Plane from V3d ), - SetPlaneOff from class View from V3d ( me : mutable ), - SetPlaneOff from class View from V3d - ( me : mutable ; Plane : Plane from V3d ) - -end Plane; diff --git a/src/V3d/V3d_Plane.cxx b/src/V3d/V3d_Plane.cxx old mode 100755 new mode 100644 index b3ba033cac..aed96f9f42 --- a/src/V3d/V3d_Plane.cxx +++ b/src/V3d/V3d_Plane.cxx @@ -1,6 +1,6 @@ // Created by: GG // Copyright (c) 1991-1999 Matra Datavision -// Copyright (c) 1999-2012 OPEN CASCADE SAS +// Copyright (c) 1999-2013 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file @@ -17,120 +17,149 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. - - -//-Version - -//-Design - -//-Warning - -//-References - -//-Language C++ 2.1 - -#include -#include -#include - +#include #include -#include #include +#include #include -//-Constructors +IMPLEMENT_STANDARD_HANDLE(V3d_Plane, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(V3d_Plane, MMgt_TShared) -V3d_Plane::V3d_Plane(const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D) +// ======================================================================= +// function : V3d_Plane +// purpose : +// ======================================================================= +V3d_Plane::V3d_Plane (const Standard_Real theA, + const Standard_Real theB, + const Standard_Real theC, + const Standard_Real theD) +: myGraphicStructure(), + myPlane (new Graphic3d_ClipPlane (gp_Pln (theA, theB, theC, theD))) { - V3d_BadValue_Raise_if( sqrt(A*A + B*B + C*C) <= 0., "V3d_Plane::V3d_Plane, bad plane coefficients"); - - MyPlane = new Visual3d_ClipPlane(A,B,C,D) ; } -//-Methods, in order - -void V3d_Plane::SetPlane(const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D) +// ======================================================================= +// function : V3d_Plane +// purpose : +// ======================================================================= +void V3d_Plane::SetPlane (const Standard_Real theA, + const Standard_Real theB, + const Standard_Real theC, + const Standard_Real theD) { - V3d_BadValue_Raise_if( sqrt(A*A + B*B + C*C) <= 0., "V3d_Plane::SetPlane, bad plane coefficients"); - - MyPlane->SetPlane(A,B,C,D) ; - if( IsDisplayed() ) + myPlane->SetEquation (gp_Pln (theA, theB, theC, theD)); + if (IsDisplayed()) + { Update(); + } } -void V3d_Plane::Display(const Handle(V3d_View)& aView, - const Quantity_Color& aColor) +// ======================================================================= +// function : Display +// purpose : +// ======================================================================= +void V3d_Plane::Display (const Handle(V3d_View)& theView, + const Quantity_Color& theColor) { - Handle(V3d_Viewer) theViewer = aView->Viewer(); - if (!MyGraphicStructure.IsNull()) - MyGraphicStructure->Clear(); + Handle(V3d_Viewer) aViewer = theView->Viewer(); + if (!myGraphicStructure.IsNull()) + { + myGraphicStructure->Clear(); + } - MyGraphicStructure = new Graphic3d_Structure(theViewer->Viewer()); - Handle(Graphic3d_Group) group = new Graphic3d_Group(MyGraphicStructure); - Handle(Graphic3d_AspectFillArea3d) aspect = new Graphic3d_AspectFillArea3d(); - Graphic3d_MaterialAspect plastic(Graphic3d_NOM_PLASTIC); - plastic.SetColor(aColor); - plastic.SetTransparency(0.5); - aView->SetTransparency(Standard_True); - aspect->SetFrontMaterial(plastic); - aspect->SetInteriorStyle (Aspect_IS_HATCH); - aspect->SetHatchStyle (Aspect_HS_GRID_DIAGONAL_WIDE); - MyGraphicStructure->SetPrimitivesAspect(aspect); + myGraphicStructure = new Graphic3d_Structure (aViewer->Viewer()); + Handle(Graphic3d_Group) aGroup = new Graphic3d_Group (myGraphicStructure); + Handle(Graphic3d_AspectFillArea3d) anAsp = new Graphic3d_AspectFillArea3d(); + Graphic3d_MaterialAspect aPlastic (Graphic3d_NOM_PLASTIC); + aPlastic.SetColor (theColor); + aPlastic.SetTransparency (0.5); + theView->SetTransparency (Standard_True); + anAsp->SetFrontMaterial (aPlastic); + anAsp->SetInteriorStyle (Aspect_IS_HATCH); + anAsp->SetHatchStyle (Aspect_HS_GRID_DIAGONAL_WIDE); + myGraphicStructure->SetPrimitivesAspect (anAsp); - const Standard_ShortReal size = (Standard_ShortReal)(0.5*theViewer->DefaultViewSize()); - const Standard_ShortReal offset = size/5000.F; + const Standard_ShortReal aSize = (Standard_ShortReal)(0.5*aViewer->DefaultViewSize()); + const Standard_ShortReal anOffset = aSize/5000.0f; Handle(Graphic3d_ArrayOfQuadrangles) aPrims = new Graphic3d_ArrayOfQuadrangles(4); - aPrims->AddVertex(-size,-size,offset); - aPrims->AddVertex(-size, size,offset); - aPrims->AddVertex( size, size,offset); - aPrims->AddVertex( size,-size,offset); - group->AddPrimitiveArray(aPrims); + aPrims->AddVertex (-aSize,-aSize, anOffset); + aPrims->AddVertex (-aSize, aSize, anOffset); + aPrims->AddVertex ( aSize, aSize, anOffset); + aPrims->AddVertex ( aSize,-aSize, anOffset); + aGroup->AddPrimitiveArray(aPrims); - MyGraphicStructure->Display(0); + myGraphicStructure->Display(0); Update(); } +// ======================================================================= +// function : Erase +// purpose : +// ======================================================================= void V3d_Plane::Erase() { - if (!MyGraphicStructure.IsNull()) MyGraphicStructure->Erase(); -} - -void V3d_Plane::Plane(Standard_Real& A, Standard_Real& B, Standard_Real& C, Standard_Real& D) const -{ - MyPlane->Plane(A,B,C,D) ; -} - -Handle(Visual3d_ClipPlane) V3d_Plane::Plane()const -{ - return MyPlane; -} - -Standard_Boolean V3d_Plane::IsDisplayed() const -{ - if( MyGraphicStructure.IsNull() ) return Standard_False; - return MyGraphicStructure->IsDisplayed(); -} - -void V3d_Plane::Update() -{ - if( !MyGraphicStructure.IsNull() ) { - TColStd_Array2OfReal matrix(1,4,1,4); - Standard_Real A,B,C,D; - MyPlane->Plane(A,B,C,D) ; - gp_Pln plan(A,B,C,D); - gp_Trsf trsf; - trsf.SetTransformation(plan.Position()); - trsf.Invert(); - for (Standard_Integer i=1; i<=3; i++){ - for (Standard_Integer j=1; j<=4; j++){ - matrix.SetValue(i,j,trsf.Value(i,j)); - } - } - matrix.SetValue(4,1,0.); - matrix.SetValue(4,2,0.); - matrix.SetValue(4,3,0.); - matrix.SetValue(4,4,1.); - MyGraphicStructure->SetTransform(matrix,Graphic3d_TOC_REPLACE); + if (!myGraphicStructure.IsNull()) + { + myGraphicStructure->Erase(); + } +} + +// ======================================================================= +// function : Plane +// purpose : +// ======================================================================= +void V3d_Plane::Plane (Standard_Real& theA, Standard_Real& theB, Standard_Real& theC, Standard_Real& theD) const +{ + const Graphic3d_ClipPlane::Equation& anEquation = myPlane->GetEquation(); + theA = anEquation[0]; + theB = anEquation[1]; + theC = anEquation[2]; + theD = anEquation[3]; +} + +// ======================================================================= +// function : IsDisplayed +// purpose : +// ======================================================================= +Standard_Boolean V3d_Plane::IsDisplayed() const +{ + if (myGraphicStructure.IsNull()) + { + return Standard_False; + } + + return myGraphicStructure->IsDisplayed(); +} + +// ======================================================================= +// function : Update +// purpose : +// ======================================================================= +void V3d_Plane::Update() +{ + if(!myGraphicStructure.IsNull()) + { + TColStd_Array2OfReal aMatrix (1, 4, 1, 4); + Standard_Real theA, theB, theC, theD; + this->Plane(theA, theB, theC, theD); + gp_Pln aGeomPln (theA, theB, theC, theD); + gp_Trsf aTransform; + aTransform.SetTransformation (aGeomPln.Position()); + aTransform.Invert(); + for (Standard_Integer i = 1; i <= 3; i++) + { + for (Standard_Integer j = 1; j <= 4; j++) + { + aMatrix.SetValue (i, j, aTransform.Value (i,j)); + } + } + + aMatrix.SetValue (4,1,0.); + aMatrix.SetValue (4,2,0.); + aMatrix.SetValue (4,3,0.); + aMatrix.SetValue (4,4,1.); + myGraphicStructure->SetTransform (aMatrix, Graphic3d_TOC_REPLACE); } } diff --git a/src/V3d/V3d_Plane.hxx b/src/V3d/V3d_Plane.hxx new file mode 100644 index 0000000000..d7bc09d214 --- /dev/null +++ b/src/V3d/V3d_Plane.hxx @@ -0,0 +1,105 @@ +// Created by: GG +// Copyright (c) 1991-1999 Matra Datavision +// Copyright (c) 1999-2013 OPEN CASCADE SAS +// +// The content of this file is subject to the Open CASCADE Technology Public +// License Version 6.5 (the "License"). You may not use the content of this file +// except in compliance with the License. Please obtain a copy of the License +// at http://www.opencascade.org and read it completely before using this file. +// +// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its +// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. +// +// The Original Code and all software distributed under the License is +// distributed on an "AS IS" basis, without warranty of any kind, and the +// Initial Developer hereby disclaims all such warranties, including without +// limitation, any warranties of merchantability, fitness for a particular +// purpose or non-infringement. Please see the License for the specific terms +// and conditions governing the rights and limitations under the License. + +#ifndef _V3d_Plane_H__ +#define _V3d_Plane_H__ + +#include +#include +#include + +DEFINE_STANDARD_HANDLE (V3d_Plane, MMgt_TShared) + +//! Obsolete clip plane presentation class. +//! Ported on new core of Graphic3d_ClipPlane approach. +//! Please access Graphic3d_ClipPlane via ClipPlane() method +//! to use it for standard clipping workflow. +//! Example of use: +//! @code +//! +//! Handle(V3d_Plane) aPlane (0, 1, 0, -20); +//! Handle(V3d_View) aView; +//! aView->AddClipPlane (aPlane->ClipPlane()); +//! +//! aPlane->Display (aView); +//! aPlane->SetPlane (0, 1, 0, -30); +//! aView->RemoveClipPlane (aPlane->ClipPlane()); +//! +//! @endcode +//! Use interface of this class to modify plane equation synchronously +//! with clipping equation. +class V3d_Plane : public MMgt_TShared +{ +public: + + //! Creates a clipping plane from plane coefficients. + Standard_EXPORT V3d_Plane (const Quantity_Parameter theA = 0.0, + const Quantity_Parameter theB = 0.0, + const Quantity_Parameter theC = 1.0, + const Quantity_Parameter theD = 0.0); + + //! Change plane equation. + Standard_EXPORT void SetPlane (const Quantity_Parameter theA, + const Quantity_Parameter theB, + const Quantity_Parameter theC, + const Quantity_Parameter theD); + + //! Display the plane representation in the choosen view. + Standard_EXPORT virtual void Display (const Handle(V3d_View)& theView, + const Quantity_Color& theColor = Quantity_NOC_GRAY); + + //! Erase the plane representation. + Standard_EXPORT void Erase(); + + //! Returns the parameters of the plane. + Standard_EXPORT void Plane (Quantity_Parameter& theA, + Quantity_Parameter& theB, + Quantity_Parameter& theC, + Quantity_Parameter& theD) const; + + //! Returns TRUE when the plane representation is displayed
+ Standard_EXPORT Standard_Boolean IsDisplayed() const; + + //! Use this method to pass clipping plane implementation for + //! standard clipping workflow. + //! @return clipping plane implementation handle. + Standard_EXPORT const Handle(Graphic3d_ClipPlane)& ClipPlane() const + { + return myPlane; + } + +private: + + //! Updates the the plane representation. + Standard_EXPORT void Update(); + +protected: + + Handle(Graphic3d_Structure) myGraphicStructure; + +private: + + Handle(Graphic3d_ClipPlane) myPlane; //!< clip plane implementation. + +public: + + DEFINE_STANDARD_RTTI(V3d_Plane) +}; + +#endif diff --git a/src/V3d/V3d_View.cdl b/src/V3d/V3d_View.cdl index 66b6ab38e4..e9543ea47c 100755 --- a/src/V3d/V3d_View.cdl +++ b/src/V3d/V3d_View.cdl @@ -101,7 +101,6 @@ uses TypeOfBackfacingModel from V3d, Viewer from V3d, Light from V3d, - Plane from V3d, View from Visual3d, ViewMapping from Visual3d, ViewOrientation from Visual3d, @@ -136,8 +135,9 @@ uses FontAspect from Font, AsciiString from TCollection, ExtendedString from TCollection, - PrintAlgo from Aspect - + PrintAlgo from Aspect, + ClipPlane_Handle from Graphic3d, + SetOfHClipPlane from Graphic3d raises BadValue from V3d, TypeMismatch from Standard, @@ -392,7 +392,7 @@ is ---Level: Public ---Purpose: Deactivate all the Lights defined in this view. - IsActiveLight( me ; aLight: Light from V3d ) + IsActiveLight( me ; aLight: Light from V3d ) returns Boolean from Standard; ---Level: Public ---Purpose: Returns TRUE when the light is active in this view. @@ -401,34 +401,6 @@ is ---Level: Public ---Purpose: Activate/Deactivate the transparency in this view. - SetPlaneOn( me : mutable ; MyPlane : Plane from V3d ) - ---Level: Public - ---Purpose: Activates the clipping plane in this view. - raises BadValue from V3d ; - ---Purpose: If No More Plane can be activated in MyView . - - SetPlaneOn( me : mutable ) - ---Level: Public - ---Purpose: Activate all the clipping planes defined in - -- this view. - raises BadValue from V3d; - ---Purpose: If No More Plane can be activated in MyView . - - SetPlaneOff( me : mutable ; MyPlane : Plane from V3d ); - ---Level: Public - ---Purpose: Desactivates the clipping plane defined - -- in this view. - - SetPlaneOff( me : mutable ); - ---Level: Public - ---Purpose: Deactivate all clipping planes defined - -- in this view. - - IsActivePlane( me ; aPlane: Plane from V3d ) - returns Boolean from Standard; - ---Level: Public - ---Purpose: Returns TRUE when the plane is active in this view. - SetImmediateUpdate(me: mutable; theImmediateUpdate: Boolean from Standard) returns Boolean from Standard; ---Purpose: sets the immediate update mode and returns the previous one. @@ -438,7 +410,7 @@ is -- Triedron methods --------------------------------------------------- - ZBufferTriedronSetup ( me : mutable; + ZBufferTriedronSetup ( me : mutable; XColor : NameOfColor from Quantity = Quantity_NOC_RED; YColor : NameOfColor from Quantity = Quantity_NOC_GREEN; ZColor : NameOfColor from Quantity = Quantity_NOC_BLUE1; @@ -1223,27 +1195,6 @@ is ActiveLight(me) returns mutable Light from V3d; ---Level: Advanced - IfMorePlanes( me ) returns Boolean; - ---Level: Advanced - ---Purpose: Returns True if One clipping plane more can be - -- activated in this View. - - InitActivePlanes(me: mutable); - ---Level: Advanced - ---Purpose: initializes an iteration on the active Planes. - - MoreActivePlanes (me) returns Boolean from Standard; - ---Level: Advanced - ---Purpose: returns true if there are more active Plane(s) to return. - - NextActivePlanes (me: mutable); - ---Level: Advanced - ---Purpose : Go to the next active Plane - -- (if there is not, ActivePlane will raise an exception) - - ActivePlane(me) returns mutable Plane from V3d; - ---Level: Advanced - Viewer ( me ) returns mutable Viewer from V3d; ---Level: Advanced ---Purpose: Returns the viewer in which the view has been created. @@ -1604,13 +1555,36 @@ is ---Purpose: returns the current state of the gl lighting -- currently used in triedron displaying + AddClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual; + ---Purpose: Adds clip plane to the view. The composition of clip planes truncates the + -- rendering space to convex volume. Number of supported clip planes can be consulted + -- by PlaneLimit method of associated Visual3d_View. Please be aware that the planes + -- which exceed the limit are igonred during rendering. + -- @param thePlane [in] the clip plane to be added to view. + + RemoveClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual; + ---Purpose: Removes clip plane from the view. + -- @param thePlane [in] the clip plane to be removed from view. + + SetClipPlanes (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d); + ---Purpose: Set clip planes to the view. The planes that have been set + -- before are removed from the view. The composition of clip planes + -- truncates the rendering space to convex volume. Number of supported + -- clip planes can be consulted by PlaneLimit method of associated + -- Visual3d_View. Please be aware that the planes which exceed the limit + -- are igonred during rendering. + -- @param thePlanes [in] the clip planes to set. + + GetClipPlanes (me) returns SetOfHClipPlane from Graphic3d; + ---C++: return const& + ---Purpose: Get clip planes. + -- @return sequence clip planes that have been set for the view fields MyType : TypeOfView from V3d is protected ; MyViewer : ViewerPointer from V3d ; MyActiveLights: ListOfTransient from V3d; - MyActivePlanes: ListOfTransient from V3d; MyView : View from Visual3d is protected ; MyViewMapping : ViewMapping from Visual3d is protected ; @@ -1626,7 +1600,6 @@ fields MyPlotter: Plotter from Graphic3d; myActiveLightsIterator: ListIteratorOfListOfTransient from TColStd; - myActivePlanesIterator: ListIteratorOfListOfTransient from TColStd; sx,sy: Integer from Standard; rx,ry: Real from Standard; diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index 4bd8b4993c..555930e501 100755 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -144,7 +144,6 @@ To solve the problem (for lack of a better solution) I make 2 passes. #include #include #include -#include #include #include #include @@ -269,10 +268,8 @@ V3d_View::V3d_View(const Handle(V3d_Viewer)& VM, const V3d_TypeOfView Type ) : MyType ( Type ), MyViewer(VM.operator->()), MyActiveLights(), -MyActivePlanes(), MyViewContext (), myActiveLightsIterator(), -myActivePlanesIterator(), SwitchSetFront(Standard_False), MyTrsf (1, 4, 1, 4), // S3892 MyProjModel(V3d_TPM_SCREEN) @@ -372,10 +369,8 @@ V3d_View::V3d_View(const Handle(V3d_Viewer)& VM,const Handle(V3d_View)& V, const MyType ( Type ), MyViewer(VM.operator->()), MyActiveLights(), -MyActivePlanes(), MyViewContext (), myActiveLightsIterator(), -myActivePlanesIterator(), SwitchSetFront(Standard_False), MyTrsf (1, 4, 1, 4), // S3892 MyProjModel(V3d_TPM_SCREEN) @@ -387,8 +382,6 @@ MyProjModel(V3d_TPM_SCREEN) for (V->InitActiveLights();V->MoreActiveLights();V->NextActiveLights()){ MyActiveLights.Append(V->ActiveLight());} - for (V->InitActivePlanes();V->MoreActivePlanes();V->NextActivePlanes()){ - MyActivePlanes.Append(V->ActivePlane());} MyViewContext = FromView->Context() ; diff --git a/src/V3d/V3d_View_2.cxx b/src/V3d/V3d_View_2.cxx index 56c29389da..8af5b3d4ca 100755 --- a/src/V3d/V3d_View_2.cxx +++ b/src/V3d/V3d_View_2.cxx @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -119,70 +118,6 @@ Standard_Boolean V3d_View::Transparency() const { return MyTransparencyFlag; } -void V3d_View::SetPlaneOn( const Handle(V3d_Plane)& ThePlane ) { - -#ifdef GER61454 - if( !MyActivePlanes.Contains(ThePlane)) { - V3d_BadValue_Raise_if( MyActivePlanes.Extent() >= MyView->PlaneLimit(), "too many planes"); - MyActivePlanes.Append(ThePlane) ; - } - MyViewContext.SetClipPlaneOn(ThePlane->Plane()) ; - MyView->SetContext(MyViewContext); -#else //GER61454 - if( !MyActivePlanes.Contains(ThePlane)) { - V3d_BadValue_Raise_if( MyActivePlanes.Extent() >= Visual3d_ClipPlane::Limit(), "too many planes"); - MyActivePlanes.Append(ThePlane) ; - MyViewContext.SetClipPlaneOn(ThePlane->Plane()) ; - - MyView->SetContext(MyViewContext); - } -#endif //GER61454 -} - -void V3d_View::SetPlaneOff( const Handle(V3d_Plane)& ThePlane ) { - - MyActivePlanes.Remove(ThePlane); - MyViewContext.SetClipPlaneOff(ThePlane->Plane()) ; - MyView->SetContext(MyViewContext) ; -} - -Standard_Boolean V3d_View::IsActivePlane(const Handle(V3d_Plane)& aPlane) const { - if( aPlane.IsNull() ) return Standard_False; - return MyActivePlanes.Contains(aPlane); -} - -void V3d_View::SetPlaneOn( ) { - -#ifdef GER61454 - for(MyViewer->InitDefinedPlanes();MyViewer->MoreDefinedPlanes();MyViewer->NextDefinedPlanes()) { - if(!MyActivePlanes.Contains(MyViewer->DefinedPlane())) { - V3d_BadValue_Raise_if( MyActivePlanes.Extent() >= MyView->PlaneLimit(), "too many planes"); - MyActivePlanes.Append(MyViewer->DefinedPlane()); - } - MyViewContext.SetClipPlaneOn(MyViewer->DefinedPlane()->Plane()); - } - MyView->SetContext(MyViewContext) ; -#else //GER61454 - for(MyViewer->InitDefinedPlanes();MyViewer->MoreDefinedPlanes();MyViewer->NextDefinedPlanes()) { - if(!MyActivePlanes.Contains(MyViewer->DefinedPlane())) { - V3d_BadValue_Raise_if( MyActivePlanes.Extent() >= Visual3d_ClipPlane::Limit(), - "too many planes"); - MyActivePlanes.Append(MyViewer->DefinedPlane()); - MyViewContext.SetClipPlaneOn(MyViewer->DefinedPlane()->Plane()); - MyView->SetContext(MyViewContext) ; - } - } -#endif //GER61454 -} - -void V3d_View::SetPlaneOff( ) { - - for(InitActivePlanes();MoreActivePlanes();NextActivePlanes()) { - MyViewContext.SetClipPlaneOff(ActivePlane()->Plane());} - MyActivePlanes.Clear(); - MyView->SetContext(MyViewContext) ; -} - void V3d_View::InitActiveLights() { myActiveLightsIterator.Initialize(MyActiveLights); } @@ -195,30 +130,6 @@ void V3d_View::NextActiveLights () { Handle(V3d_Light) V3d_View::ActiveLight() const { return (Handle(V3d_Light)&)(myActiveLightsIterator.Value());} - -void V3d_View::InitActivePlanes() { -myActivePlanesIterator.Initialize(MyActivePlanes); -} -Standard_Boolean V3d_View::MoreActivePlanes () const { - return myActivePlanesIterator.More(); -} -void V3d_View::NextActivePlanes () { - myActivePlanesIterator.Next(); -} - -Handle(V3d_Plane) V3d_View::ActivePlane() const { - return (Handle(V3d_Plane)&)(myActivePlanesIterator.Value());} - -Standard_Boolean V3d_View::IfMorePlanes() const { - -#ifdef GER61454 - return MyActivePlanes.Extent() < MyView->PlaneLimit(); -#else - return MyActivePlanes.Extent() < Visual3d_ClipPlane::Limit(); -#endif - -} - Standard_Boolean V3d_View::IfMoreLights() const { #ifdef GER61454 @@ -228,3 +139,50 @@ Standard_Boolean V3d_View::IfMoreLights() const { return MyActiveLights.Extent(); #endif } + +//======================================================================= +//function : AddClipPlane +//purpose : +//======================================================================= +void V3d_View::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) +{ + Graphic3d_SetOfHClipPlane aCurrPlanes = MyViewContext.GetClipPlanes(); + if (!aCurrPlanes.Add (thePlane)) + return; + + MyViewContext.SetClipPlanes (aCurrPlanes); + MyView->SetContext (MyViewContext) ; +} + +//======================================================================= +//function : RemoveClipPlane +//purpose : +//======================================================================= +void V3d_View::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) +{ + Graphic3d_SetOfHClipPlane aCurrPlanes = MyViewContext.GetClipPlanes(); + if (!aCurrPlanes.Remove (thePlane)) + return; + + MyViewContext.SetClipPlanes (aCurrPlanes); + MyView->SetContext (MyViewContext) ; +} + +//======================================================================= +//function : SetClipPlanes +//purpose : +//======================================================================= +void V3d_View::SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes) +{ + MyViewContext.SetClipPlanes (thePlanes); + MyView->SetContext (MyViewContext) ; +} + +//======================================================================= +//function : GetClipPlanes +//purpose : +//======================================================================= +const Graphic3d_SetOfHClipPlane& V3d_View::GetClipPlanes() const +{ + return MyViewContext.GetClipPlanes(); +} diff --git a/src/V3d/V3d_Viewer.cdl b/src/V3d/V3d_Viewer.cdl index 02a9f7c9af..f6e63512bf 100755 --- a/src/V3d/V3d_Viewer.cdl +++ b/src/V3d/V3d_Viewer.cdl @@ -51,7 +51,6 @@ uses TypeOfOrientation from V3d, View from V3d, Light from V3d, - Plane from V3d, ListOfTransient from V3d, ListIteratorOfListOfTransient from TColStd, SequenceOfInteger from TColStd, @@ -431,28 +430,6 @@ is DefinedLight(me) returns Light from V3d; ---Level: Advanced - AddPlane( me: mutable; MyPlane : Plane from V3d); - ---Purpose: Adds Plane in Sequence Of Planes. - - DelPlane( me: mutable; MyPlane : Plane from V3d); - ---Purpose: Delete Plane in Sequence Of Planes. - - InitDefinedPlanes(me: mutable); - ---Level: Advanced - ---Purpose: initializes an iteration on the Defined Planes. - - MoreDefinedPlanes (me) returns Boolean from Standard; - ---Level: Advanced - ---Purpose: returns true if there are more Defined Plane(s) to return. - - NextDefinedPlanes (me: mutable); - ---Level: Advanced - ---Purpose : Go to the next Defined Plane - -- (if there is not, DefinedPlane will raise an exception) - - DefinedPlane(me) returns Plane from V3d; - ---Level: Advanced - Viewer (me) returns mutable ViewManager ; ---Level: Advanced ---Purpose: Returns the viewer associated to Visual3d . @@ -714,7 +691,6 @@ fields MyActiveViews: ListOfTransient from V3d; MyDefinedLights: ListOfTransient from V3d; MyActiveLights: ListOfTransient from V3d; - MyDefinedPlanes: ListOfTransient from V3d; MyBackground: Background from Aspect ; MyGradientBackground: GradientBackground from Aspect ; MyViewSize: Real ; @@ -731,7 +707,6 @@ fields myDefinedViewsIterator: ListIteratorOfListOfTransient from TColStd; myActiveLightsIterator: ListIteratorOfListOfTransient from TColStd; myDefinedLightsIterator: ListIteratorOfListOfTransient from TColStd; - myDefinedPlanesIterator: ListIteratorOfListOfTransient from TColStd; myComputedMode: Boolean from Standard; myDefaultComputedMode: Boolean from Standard; myPrivilegedPlane: Ax3 from gp; @@ -751,6 +726,5 @@ friends class View from V3d, class Light from V3d, - class Plane from V3d, SetPlane from package V3d (aViewer: Viewer from V3d; x1,y1,z1,x2,y2,z2: Length from Quantity) end Viewer; diff --git a/src/V3d/V3d_Viewer.cxx b/src/V3d/V3d_Viewer.cxx index 59719bba14..f3ccb78cf7 100755 --- a/src/V3d/V3d_Viewer.cxx +++ b/src/V3d/V3d_Viewer.cxx @@ -73,12 +73,10 @@ MyDefinedViews(), MyActiveViews(), MyDefinedLights(), MyActiveLights(), -MyDefinedPlanes(), myActiveViewsIterator(), myDefinedViewsIterator(), myActiveLightsIterator(), myDefinedLightsIterator(), -myDefinedPlanesIterator(), myComputedMode (theComputedMode), myDefaultComputedMode (theDefaultComputedMode), myPrivilegedPlane (gp_Ax3 (gp_Pnt (0.,0.,0), gp_Dir (0.,0.,1.), gp_Dir (1.,0.,0.))), @@ -369,16 +367,6 @@ void V3d_Viewer::DelView( const Handle(V3d_View)& TheView ) { MyDefinedViews.Remove(TheView); } -void V3d_Viewer::AddPlane( const Handle(V3d_Plane)& ThePlane ) { - - MyDefinedPlanes.Append(ThePlane) ; -} - -void V3d_Viewer::DelPlane( const Handle(V3d_Plane)& ThePlane ) { - - MyDefinedPlanes.Remove(ThePlane); -} - //======================================================================= //function : AddZLayer //purpose : diff --git a/src/V3d/V3d_Viewer_1.cxx b/src/V3d/V3d_Viewer_1.cxx index c940e974c7..f8eb1679e7 100755 --- a/src/V3d/V3d_Viewer_1.cxx +++ b/src/V3d/V3d_Viewer_1.cxx @@ -70,16 +70,3 @@ void V3d_Viewer::NextDefinedLights () { } Handle(V3d_Light) V3d_Viewer::DefinedLight() const { return (Handle(V3d_Light)&)(myDefinedLightsIterator.Value());} - -void V3d_Viewer::InitDefinedPlanes() { -myDefinedPlanesIterator.Initialize(MyDefinedPlanes); -} -Standard_Boolean V3d_Viewer::MoreDefinedPlanes () const { - return myDefinedPlanesIterator.More(); -} -void V3d_Viewer::NextDefinedPlanes () { - myDefinedPlanesIterator.Next(); -} -Handle(V3d_Plane) V3d_Viewer::DefinedPlane() const { - return (Handle(V3d_Plane)&)(myDefinedPlanesIterator.Value());} - diff --git a/src/ViewerTest/ViewerTest.cdl b/src/ViewerTest/ViewerTest.cdl index 86645bfe5c..b7dc7b543b 100755 --- a/src/ViewerTest/ViewerTest.cdl +++ b/src/ViewerTest/ViewerTest.cdl @@ -194,6 +194,7 @@ is GetColorFromName(name: CString from Standard) returns NameOfColor from Quantity; - + RedrawAllViews; + ---Purpose: redraws all defined views. end; diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index e9bd78e584..5651f2f0b4 100755 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -2854,181 +2853,6 @@ static int VDrawSphere (Draw_Interpretor& /*di*/, Standard_Integer argc, const c return 0; } -//=============================================================================================== -//function : VClipPlane -//purpose : -//=============================================================================================== -static int VClipPlane (Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv) -{ - Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext(); - Handle(V3d_View) aView = ViewerTest::CurrentView(); - Standard_Real coeffA, coeffB, coeffC, coeffD; - if (aViewer.IsNull() || aView.IsNull()) - { - std::cout << "Viewer not initialized!\n"; - return 1; - } - - // count an active planes count - Standard_Integer aNewPlaneId = 1; - Standard_Integer anActivePlanes = 0; - for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->NextDefinedPlanes(), ++aNewPlaneId) - { - Handle(V3d_Plane) aPlaneV3d = aViewer->DefinedPlane(); - if (aView->IsActivePlane (aPlaneV3d)) - { - ++anActivePlanes; - } - } - - if (argc == 1) - { - // just show info about existing planes - Standard_Integer aPlaneId = 1; - std::cout << "Active planes: " << anActivePlanes << " from maximal " << aView->View()->PlaneLimit() << "\n"; - for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->NextDefinedPlanes(), ++aPlaneId) - { - Handle(V3d_Plane) aPlaneV3d = aViewer->DefinedPlane(); - aPlaneV3d->Plane (coeffA, coeffB, coeffC, coeffD); - gp_Pln aPlane (coeffA, coeffB, coeffC, coeffD); - const gp_Pnt& aLoc = aPlane.Location(); - const gp_Dir& aNor = aPlane.Axis().Direction(); - Standard_Boolean isActive = aView->IsActivePlane (aPlaneV3d); - std::cout << "Plane #" << aPlaneId - << " " << aLoc.X() << " " << aLoc.Y() << " " << aLoc.Z() - << " " << aNor.X() << " " << aNor.Y() << " " << aNor.Z() - << (isActive ? " on" : " off") - << (aPlaneV3d->IsDisplayed() ? ", displayed" : ", hidden") - << "\n"; - } - if (aPlaneId == 1) - { - std::cout << "No defined clipping planes\n"; - } - return 0; - } - else if (argc == 2 || argc == 3) - { - Standard_Integer aPlaneIdToOff = (argc == 3) ? Draw::Atoi (argv[1]) : 1; - Standard_Boolean toIterateAll = (argc == 2); - TCollection_AsciiString isOnOffStr ((argc == 3) ? argv[2] : argv[1]); - isOnOffStr.LowerCase(); - Standard_Integer aPlaneId = 1; - for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->NextDefinedPlanes(), ++aPlaneId) - { - if (aPlaneIdToOff == aPlaneId || toIterateAll) - { - Handle(V3d_Plane) aPlaneV3d = aViewer->DefinedPlane(); - if (isOnOffStr.Search ("off") >= 0) - { - aView->SetPlaneOff (aPlaneV3d); - std::cout << "Clipping plane #" << aPlaneId << " was disabled\n"; - } - else if (isOnOffStr.Search ("on") >= 0) - { - // avoid z-fighting glitches - aPlaneV3d->Erase(); - if (!aView->IsActivePlane (aPlaneV3d)) - { - if (anActivePlanes < aView->View()->PlaneLimit()) - { - aView->SetPlaneOn (aPlaneV3d); - std::cout << "Clipping plane #" << aPlaneId << " was enabled\n"; - } - else - { - std::cout << "Maximal active planes limit exceeded (" << anActivePlanes << ")\n" - << "You should disable or remove some existing plane to activate this one\n"; - } - } - else - { - std::cout << "Clipping plane #" << aPlaneId << " was already enabled\n"; - } - } - else if (isOnOffStr.Search ("del") >= 0 || isOnOffStr.Search ("rem") >= 0) - { - aPlaneV3d->Erase(); // not performed on destructor!!! - aView->SetPlaneOff (aPlaneV3d); - aViewer->DelPlane (aPlaneV3d); - std::cout << "Clipping plane #" << aPlaneId << " was removed\n"; - if (toIterateAll) - { - for (aViewer->InitDefinedPlanes(); aViewer->MoreDefinedPlanes(); aViewer->InitDefinedPlanes(), ++aPlaneId) - { - aPlaneV3d = aViewer->DefinedPlane(); - aPlaneV3d->Erase(); // not performed on destructor!!! - aView->SetPlaneOff (aPlaneV3d); - aViewer->DelPlane (aPlaneV3d); - std::cout << "Clipping plane #" << aPlaneId << " was removed\n"; - } - break; - } - else - { - break; - } - } - else if (isOnOffStr.Search ("disp") >= 0 || isOnOffStr.Search ("show") >= 0) - { - // avoid z-fighting glitches - aView->SetPlaneOff (aPlaneV3d); - aPlaneV3d->Display (aView); - std::cout << "Clipping plane #" << aPlaneId << " was shown and disabled\n"; - } - else if (isOnOffStr.Search ("hide") >= 0) - { - aPlaneV3d->Erase(); - std::cout << "Clipping plane #" << aPlaneId << " was hidden\n"; - } - else - { - std::cout << "Usage: " << argv[0] << " [x y z dx dy dz] [planeId {on/off/del/display/hide}]\n"; - return 1; - } - } - } - if (aPlaneIdToOff >= aPlaneId && !toIterateAll) - { - std::cout << "Clipping plane with id " << aPlaneIdToOff << " not found!\n"; - return 1; - } - aView->Update(); - return 0; - } - else if (argc != 7) - { - std::cout << "Usage: " << argv[0] << " [x y z dx dy dz] [planeId {on/off/del/display/hide}]\n"; - return 1; - } - - Standard_Real aLocX = Draw::Atof (argv[1]); - Standard_Real aLocY = Draw::Atof (argv[2]); - Standard_Real aLocZ = Draw::Atof (argv[3]); - Standard_Real aNormDX = Draw::Atof (argv[4]); - Standard_Real aNormDY = Draw::Atof (argv[5]); - Standard_Real aNormDZ = Draw::Atof (argv[6]); - - Handle(V3d_Plane) aPlaneV3d = new V3d_Plane(); - gp_Pln aPlane (gp_Pnt (aLocX, aLocY, aLocZ), gp_Dir (aNormDX, aNormDY, aNormDZ)); - aPlane.Coefficients (coeffA, coeffB, coeffC, coeffD); - aPlaneV3d->SetPlane(coeffA, coeffB, coeffC, coeffD); - - aViewer->AddPlane (aPlaneV3d); // add to defined planes list - std::cout << "Added clipping plane #" << aNewPlaneId << "\n"; - if (anActivePlanes < aView->View()->PlaneLimit()) - { - aView->SetPlaneOn (aPlaneV3d); // add to enabled planes list - aView->Update(); - } - else - { - std::cout << "Maximal active planes limit exceeded (" << anActivePlanes << ")\n" - << "You should disable or remove some existing plane to activate the new one\n"; - } - return 0; -} - //============================================================================= //function : VComputeHLR //purpose : @@ -4792,10 +4616,6 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "vdrawsphere: vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]\n", __FILE__,VDrawSphere,group); - theCommands.Add("vclipplane", - "vclipplane : vclipplane [x y z dx dy dz] [planeId {on/off/del/display/hide}]", - __FILE__,VClipPlane,group); - theCommands.Add ("vsetlocation", "vsetlocation : name x y z; set new location for an interactive object", __FILE__, VSetLocation, group); diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 78cabc8b0e..3454c1c0f6 100755 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -38,9 +38,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -68,6 +70,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef WNT #undef DrawText @@ -504,7 +514,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft aPxWidth = thePxWidth; if (thePxHeight != 0) aPxHeight = thePxHeight; - + // Get graphic driver (create it or get from another view) if (!ViewerTest_myDrivers.IsBound1 (aViewNames.GetDriverName())) { @@ -656,7 +666,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft // NIS setup Handle(NIS_View) aView = new NIS_View (a3DViewer, VT_GetWindow()); - + ViewerTest::CurrentView(aView); ViewerTest_myViews.Bind (aViewNames.GetViewName(), aView); TheNISContext()->AttachView (aView); @@ -689,7 +699,7 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft #endif VT_GetWindow()->Map(); - + // Set the handle of created view in the event manager ViewerTest::ResetEventManager(); @@ -702,6 +712,20 @@ TCollection_AsciiString ViewerTest::ViewerInit (const Standard_Integer thePxLeft return aViewNames.GetViewName(); } +//============================================================================== +//function : RedrawAllViews +//purpose : Redraw all created views +//============================================================================== +void ViewerTest::RedrawAllViews() +{ + NCollection_DoubleMap::Iterator aViewIt(ViewerTest_myViews); + for (; aViewIt.More(); aViewIt.Next()) + { + const Handle(V3d_View)& aView = aViewIt.Key2(); + aView->Redraw(); + } +} + //============================================================================== //function : SplitParameter //purpose : Split parameter string to parameter name an patameter value @@ -1073,7 +1097,7 @@ static int VClose (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const ch } TCollection_AsciiString anInputString(theArgVec[1]); - + // Create list to iterate and remove views from the map of views NCollection_List aViewList; if ( strcasecmp( anInputString.ToCString(), "ALL" ) == 0 ) @@ -1297,7 +1321,7 @@ void VT_ProcessKeyPress (const char* buf_ret) } aContext->UpdateCurrentViewer(); - + } else if ( !strcasecmp(buf_ret, "S") ) { // SHADING @@ -2053,7 +2077,7 @@ int max( int a, int b ) int ViewerMainLoop(Standard_Integer argc, const char** argv) -{ +{ static XEvent aReport; Standard_Boolean pick = argc > 0; Display *aDisplay = GetDisplayConnection()->GetDisplay(); @@ -2275,13 +2299,13 @@ static void VProcessEvents(ClientData,int) anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next()) { anEventNumbers.Append(XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay())); - } + } // Handle events for every display int anEventIter = 0; for (NCollection_DoubleMap ::Iterator anIter (ViewerTest_myDrivers); anIter.More(); anIter.Next(), anEventIter++) { - for (int i = 0; i < anEventNumbers.Value(anEventIter) && + for (int i = 0; i < anEventNumbers.Value(anEventIter) && XPending (anIter.Key2()->GetDisplayConnection()->GetDisplay()) > 0; ++i) { SetDisplayConnection (anIter.Key2()->GetDisplayConnection()); @@ -2291,9 +2315,9 @@ static void VProcessEvents(ClientData,int) return; } } - + SetDisplayConnection (ViewerTest::GetAISContext()->CurrentViewer()->Driver()->GetDisplayConnection()); - + } #endif @@ -4789,6 +4813,433 @@ static int VTextureEnv (Draw_Interpretor& /*theDI*/, Standard_Integer theArgNb, return 0; } +//=============================================================================================== +//function : VClipPlane +//purpose : +//=============================================================================================== +static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec) +{ + // use short-cut for created clip planes map of created (or "registered by name") clip planes + typedef NCollection_DataMap MapOfPlanes; + static MapOfPlanes aRegPlanes; + + if (theArgsNb < 2) + { + theDi << theArgVec[0] << ": command argument is required. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aCommand (theArgVec[1]); + + // print maximum number of planes for current viewer + if (aCommand == "maxplanes") + { + if (theArgsNb < 3) + { + theDi << theArgVec[0] << ": view name is required. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aViewName (theArgVec[2]); + + if (!ViewerTest_myViews.IsBound1 (aViewName)) + { + theDi << theArgVec[0] << ": view is not found.\n"; + return 1; + } + + const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName); + + theDi << theArgVec[0] << ": " + << aView->Viewer()->Driver()->InquirePlaneLimit() + << " plane slots provided by driver." + << " Note that 2 more planes might be used (reserved for z-clipping).\n"; + + return 0; + } + + // create / delete plane instance + if (aCommand == "create" || aCommand == "delete" || aCommand == "clone") + { + if (theArgsNb < 3) + { + theDi << theArgVec[0] << ": plane name is required. Type help for more information.\n"; + return 1; + } + + Standard_Boolean toCreate = (aCommand == "create"); + Standard_Boolean toClone = (aCommand == "clone"); + TCollection_AsciiString aPlane (theArgVec[2]); + + if (toCreate) + { + if (aRegPlanes.IsBound (aPlane)) + { + theDi << theArgVec[0] << ": plane name is in use.\n"; + return 1; + } + + aRegPlanes.Bind (aPlane, new Graphic3d_ClipPlane()); + } + else if (toClone) // toClone + { + if (!aRegPlanes.IsBound (aPlane)) + { + theDi << theArgVec[0] << ": no such plane.\n"; + return 1; + } + + if (theArgsNb < 4) + { + theDi << theArgVec[0] << ": enter name for new plane. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aClone (theArgVec[3]); + if (aRegPlanes.IsBound (aClone)) + { + theDi << theArgVec[0] << ": plane name is in use.\n"; + return 1; + } + + const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane); + + aRegPlanes.Bind (aClone, aClipPlane->Clone()); + } + else// toDelete + { + if (!aRegPlanes.IsBound (aPlane)) + { + theDi << theArgVec[0] << ": no such plane.\n"; + return 1; + } + + Handle(Graphic3d_ClipPlane) aClipPlane = aRegPlanes.Find (aPlane); + aRegPlanes.UnBind (aPlane); + + ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName anIObjIt (GetMapOfAIS()); + for (; anIObjIt.More(); anIObjIt.Next()) + { + Handle(PrsMgr_PresentableObject) aPrs = Handle(PrsMgr_PresentableObject)::DownCast (anIObjIt.Key1()); + aPrs->RemoveClipPlane(aClipPlane); + } + + NCollection_DoubleMap::Iterator aViewIt(ViewerTest_myViews); + for (; aViewIt.More(); aViewIt.Next()) + { + const Handle(V3d_View)& aView = aViewIt.Key2(); + aView->RemoveClipPlane(aClipPlane); + } + + ViewerTest::RedrawAllViews(); + } + + return 0; + } + + // set / unset plane command + if (aCommand == "set" || aCommand == "unset") + { + if (theArgsNb < 4) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_Boolean toSet = (aCommand == "set"); + TCollection_AsciiString aPlane (theArgVec [2]); + if (!aRegPlanes.IsBound (aPlane)) + { + theDi << theArgVec[0] << ": no such plane.\n"; + return 1; + } + + const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane); + + TCollection_AsciiString aTarget (theArgVec [3]); + if (aTarget != "object" && aTarget != "view") + { + theDi << theArgVec[0] << ": invalid target.\n"; + return 1; + } + + if (aTarget == "object" || aTarget == "view") + { + if (theArgsNb < 5) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_Boolean isObject = (aTarget == "object"); + + for (Standard_Integer anIt = 4; anIt < theArgsNb; ++anIt) + { + TCollection_AsciiString anEntityName (theArgVec[anIt]); + if (isObject) // to object + { + if (!GetMapOfAIS().IsBound2 (anEntityName)) + { + theDi << theArgVec[0] << ": can not find IO with name " << anEntityName << ".\n"; + continue; + } + + Handle(AIS_InteractiveObject) aIObj = + Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anEntityName)); + + if (toSet) + aIObj->AddClipPlane (aClipPlane); + else + aIObj->RemoveClipPlane (aClipPlane); + } + else // to view + { + if (!ViewerTest_myViews.IsBound1 (anEntityName)) + { + theDi << theArgVec[0] << ": can not find View with name " << anEntityName << ".\n"; + continue; + } + + Handle(V3d_View) aView = ViewerTest_myViews.Find1(anEntityName); + if (toSet) + aView->AddClipPlane (aClipPlane); + else + aView->RemoveClipPlane (aClipPlane); + } + } + + ViewerTest::RedrawAllViews(); + } + + return 0; + } + + // change plane command + if (aCommand == "change") + { + if (theArgsNb < 4) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aPlane (theArgVec [2]); + if (!aRegPlanes.IsBound (aPlane)) + { + theDi << theArgVec[0] << ": no such plane.\n"; + return 1; + } + + const Handle(Graphic3d_ClipPlane)& aClipPlane = aRegPlanes.Find (aPlane); + + TCollection_AsciiString aChangeArg (theArgVec [3]); + if (aChangeArg != "on" && aChangeArg != "off" && aChangeArg != "capping" && aChangeArg != "equation") + { + theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n"; + return 1; + } + + if (aChangeArg == "on" || aChangeArg == "off") // on / off + { + aClipPlane->SetOn (aChangeArg == "on"); + } + else if (aChangeArg == "equation") // change equation + { + if (theArgsNb < 8) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_Real aCoeffA = atof (theArgVec [4]); + Standard_Real aCoeffB = atof (theArgVec [5]); + Standard_Real aCoeffC = atof (theArgVec [6]); + Standard_Real aCoeffD = atof (theArgVec [7]); + aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD)); + } + else if (aChangeArg == "capping") // change capping aspects + { + if (theArgsNb < 5) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aCappingArg (theArgVec [4]); + if (aCappingArg != "on" && aCappingArg != "off" && + aCappingArg != "color" && aCappingArg != "texname" && + aCappingArg != "texscale" && aCappingArg != "texorigin" && + aCappingArg != "texrotate" && aCappingArg != "hatch") + { + theDi << theArgVec[0] << ": invalid arguments. Type help for more information.\n"; + return 1; + } + + if (aCappingArg == "on" || aCappingArg == "off") // on / off capping + { + aClipPlane->SetCapping (aCappingArg == "on"); + } + else if (aCappingArg == "color") // color aspect for capping + { + if (theArgsNb < 8) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_Real aRed = atof (theArgVec [5]); + Standard_Real aGrn = atof (theArgVec [6]); + Standard_Real aBlu = atof (theArgVec [7]); + + Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial(); + aMat.SetColor (Quantity_Color (aRed, aGrn, aBlu, Quantity_TOC_RGB)); + aClipPlane->SetCappingMaterial (aMat); + } + else if (aCappingArg == "texname") // texture name + { + if (theArgsNb < 6) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aTextureName (theArgVec [5]); + + Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual(aTextureName); + if (!aTexture->IsDone ()) + { + aClipPlane->SetCappingTexture (NULL); + } + else + { + aTexture->EnableModulate(); + aTexture->EnableRepeat(); + aClipPlane->SetCappingTexture (aTexture); + } + } + else if (aCappingArg == "texscale") // texture scale + { + if (aClipPlane->CappingTexture().IsNull()) + { + theDi << theArgVec[0] << ": no texture is set.\n"; + return 1; + } + + if (theArgsNb < 7) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_ShortReal aSx = (Standard_ShortReal)atof (theArgVec [5]); + Standard_ShortReal aSy = (Standard_ShortReal)atof (theArgVec [6]); + + aClipPlane->CappingTexture()->GetParams()->SetScale (Graphic3d_Vec2 (aSx, aSy)); + } + else if (aCappingArg == "texorigin") // texture origin + { + if (aClipPlane->CappingTexture().IsNull()) + { + theDi << theArgVec[0] << ": no texture is set.\n"; + return 1; + } + + if (theArgsNb < 7) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_ShortReal aTx = (Standard_ShortReal)atof (theArgVec [5]); + Standard_ShortReal aTy = (Standard_ShortReal)atof (theArgVec [6]); + + aClipPlane->CappingTexture()->GetParams()->SetTranslation (Graphic3d_Vec2 (aTx, aTy)); + } + else if (aCappingArg == "texrotate") // texture rotation + { + if (aClipPlane->CappingTexture().IsNull()) + { + theDi << theArgVec[0] << ": no texture is set.\n"; + return 1; + } + + if (theArgsNb < 6) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + Standard_ShortReal aRot = (Standard_ShortReal)atof (theArgVec[5]); + + aClipPlane->CappingTexture()->GetParams()->SetRotation (aRot); + } + else if (aCappingArg == "hatch") // hatch style + { + if (theArgsNb < 6) + { + theDi << theArgVec[0] << ": need more arguments. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aHatchStr (theArgVec [5]); + if (aHatchStr == "on") + { + aClipPlane->SetCappingHatchOn(); + } + else if (aHatchStr == "off") + { + aClipPlane->SetCappingHatchOff(); + } + else + { + aClipPlane->SetCappingHatch ((Aspect_HatchStyle)atoi (theArgVec[5])); + } + } + } + + ViewerTest::RedrawAllViews(); + + return 0; + } + + theDi << theArgVec[0] << ": invalid command. Type help for more information.\n"; + return 1; +} + +//=============================================================================================== +//function : VSetTextureMode +//purpose : +//=============================================================================================== +static int VSetTextureMode (Draw_Interpretor& theDi, Standard_Integer theArgsNb, const char** theArgVec) +{ + if (theArgsNb < 3) + { + theDi << theArgVec[0] << ": insufficient command arguments. Type help for more information.\n"; + return 1; + } + + TCollection_AsciiString aViewName (theArgVec[1]); + if (!ViewerTest_myViews.IsBound1 (aViewName)) + { + theDi << theArgVec[0] << ": view is not found.\n"; + return 1; + } + + const Handle(V3d_View)& aView = ViewerTest_myViews.Find1 (aViewName); + switch (atoi (theArgVec[2])) + { + case 0: aView->SetSurfaceDetail (V3d_TEX_NONE); break; + case 1: aView->SetSurfaceDetail (V3d_TEX_ENVIRONMENT); break; + case 2: aView->SetSurfaceDetail (V3d_TEX_ALL); break; + default: + theDi << theArgVec[0] << ": invalid mode.\n"; + return 1; + } + + aView->Redraw(); + return 0; +} + //======================================================================= //function : ViewerCommands //purpose : @@ -5037,4 +5488,29 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "If shapes are not given HLR algoithm of given type is applied" " to all shapes in the view\n", __FILE__,VHLRType,group); + theCommands.Add("vclipplane", "vclipplane usage: \n" + " maxplanes - get plane limit for view.\n" + " create - create new plane.\n" + " delete - delete plane.\n" + " clone - clone the plane definition.\n" + " set/unset object - set/unset plane for IO.\n" + " set/unset view - set/unset plane for view.\n" + " change on/off - turn clipping on/off.\n" + " change equation - change plane equation.\n" + " change capping on/off - turn capping on/off.\n" + " change capping color - set color.\n" + " change capping texname - set texture.\n" + " change capping texscale - set tex scale.\n" + " change capping texorigin - set tex origin.\n" + " change capping texrotate - set tex rotation.\n" + " change capping hatch on/off/ - set hatching mask.\n" + " please use VSetTextureMode command to enable texture rendering in view.\n" + , __FILE__, VClipPlane, group); + theCommands.Add("vsettexturemode", "vsettexturemode view_name mode \n" + " mode can be:\n" + " 0 - no textures enabled in view.\n" + " 1 - only environment textures enabled.\n" + " 2 - all textures enabled.\n" + " this command sets texture details mode for the specified view.\n" + , __FILE__, VSetTextureMode, group); } diff --git a/src/Visual3d/Visual3d.cdl b/src/Visual3d/Visual3d.cdl index 3e50348f99..726a0cdae4 100755 --- a/src/Visual3d/Visual3d.cdl +++ b/src/Visual3d/Visual3d.cdl @@ -42,7 +42,7 @@ package Visual3d -- The visualiser manages the structures, the views, the -- light sources, and object picking. - ---Keywords: View, Light, Plane, Pick + ---Keywords: View, Light, Pick ---Warning: ---References: @@ -205,11 +205,6 @@ is -- Category: The classes ------------------------ - class ClipPlane; - ---Purpose: This class allows the creation and update of a - -- clipping plane in the space model. - ---Category: The classes - class ContextPick; ---Purpose: This class allows the creation and update of a -- pick context for one view of the viewer. @@ -317,15 +312,6 @@ is (PickPath from Visual3d, SequenceOfPickPath); ---Category: Instantiated classes - class SetOfClipPlane instantiates - Set from TCollection (ClipPlane from Visual3d); - ---Category: Instantiated classes - - class HSetOfClipPlane instantiates - HSet from TCollection - (ClipPlane from Visual3d, SetOfClipPlane); - ---Category: Instantiated classes - class SetOfLight instantiates Set from TCollection (Light from Visual3d); ---Category: Instantiated classes diff --git a/src/Visual3d/Visual3d_ClipPlane.cdl b/src/Visual3d/Visual3d_ClipPlane.cdl deleted file mode 100755 index 39a56105e3..0000000000 --- a/src/Visual3d/Visual3d_ClipPlane.cdl +++ /dev/null @@ -1,119 +0,0 @@ --- Created on: 1991-09-06 --- Created by: NW,JPB,CAL --- Copyright (c) 1991-1999 Matra Datavision --- Copyright (c) 1999-2012 OPEN CASCADE SAS --- --- The content of this file is subject to the Open CASCADE Technology Public --- License Version 6.5 (the "License"). You may not use the content of this file --- except in compliance with the License. Please obtain a copy of the License --- at http://www.opencascade.org and read it completely before using this file. --- --- The Initial Developer of the Original Code is Open CASCADE S.A.S., having its --- main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. --- --- The Original Code and all software distributed under the License is --- distributed on an "AS IS" basis, without warranty of any kind, and the --- Initial Developer hereby disclaims all such warranties, including without --- limitation, any warranties of merchantability, fitness for a particular --- purpose or non-infringement. Please see the License for the specific terms --- and conditions governing the rights and limitations under the License. - - -class ClipPlane from Visual3d inherits TShared - - ---Version: - - ---Purpose: This class allows the definition and update - -- of clipping planes in the space model. - - ---Keywords: Clipping Plane, Model Clipping - - ---Warning: - ---References: - -uses - - CPlane from Graphic3d - -is - - Create ( ACoefA : Real from Standard; - ACoefB : Real from Standard; - ACoefC : Real from Standard; - ACoefD : Real from Standard ) - returns mutable ClipPlane from Visual3d; - ---Level: Internal - ---Purpose: Creates a clipping plane from the equation : - -- *X + *Y + *Z + = 0.0 - - --------------------------------------------------- - -- Category: Methods to modify the class definition - --------------------------------------------------- - - SetPlane ( me : mutable; - ACoefA : Real from Standard; - ACoefB : Real from Standard; - ACoefC : Real from Standard; - ACoefD : Real from Standard ) - is static; - ---Level: Internal - ---Purpose: Modifies the plane equation. - ---Category: Methods to modify the class definition - - -------------------------- - -- Category: Class methods - -------------------------- - - Limit ( myclass ) - returns Integer from Standard; - ---Level: Internal - ---Purpose: Maximum number of activatable clipping planes. - ---Category: Class methods - - ---------------------------- - -- Category: Inquire methods - ---------------------------- - - Plane ( me; - ACoefA : out Real from Standard; - ACoefB : out Real from Standard; - ACoefC : out Real from Standard; - ACoefD : out Real from Standard ) - is static; - ---Level: Internal - ---Purpose: Returns the values of the clipping plane . - ---Category: Inquire methods - - ---------------------------- - -- Category: Private methods - ---------------------------- - - Identification ( me ) - returns Integer from Standard - is static private; - ---Level: Internal - ---Purpose: Returns the plane identification. - ---Category: Private methods - --- - -fields - --- --- Class : Visual3d_ClipPlane --- --- Purpose : Declaration of variables specific to the --- clipping plane model --- --- Reminders : A clipping plane is defined by its equation --- Equation : A*X + B*Y + C*Z + D = 0 --- - - -- the associated C structure - MyCPlane : CPlane from Graphic3d; - -friends - - class View from Visual3d - -end ClipPlane; diff --git a/src/Visual3d/Visual3d_ClipPlane.cxx b/src/Visual3d/Visual3d_ClipPlane.cxx deleted file mode 100755 index bbb670d5fe..0000000000 --- a/src/Visual3d/Visual3d_ClipPlane.cxx +++ /dev/null @@ -1,103 +0,0 @@ -// Created by: NW,JPB,CAL -// Copyright (c) 1991-1999 Matra Datavision -// Copyright (c) 1999-2012 OPEN CASCADE SAS -// -// The content of this file is subject to the Open CASCADE Technology Public -// License Version 6.5 (the "License"). You may not use the content of this file -// except in compliance with the License. Please obtain a copy of the License -// at http://www.opencascade.org and read it completely before using this file. -// -// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its -// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. -// -// The Original Code and all software distributed under the License is -// distributed on an "AS IS" basis, without warranty of any kind, and the -// Initial Developer hereby disclaims all such warranties, including without -// limitation, any warranties of merchantability, fitness for a particular -// purpose or non-infringement. Please see the License for the specific terms -// and conditions governing the rights and limitations under the License. - - - - -//-Version - -//-Design Declaration des variables specifiques aux plans de -// clipping modele - -//-Warning Un plan de clipping est defini par son equation ou -// par un point et sa normale -// Equation : A*X + B*Y + C*Z + D = 0 - -//-References - -//-Language C++ 2.0 - -//-Declarations - -// for the class -#include - -#include - -//-Aliases - -//-Global data definitions - -//-Constructors - -//-Destructors - -//-Methods, in order - -Visual3d_ClipPlane::Visual3d_ClipPlane (const Standard_Real ACoefA, const Standard_Real ACoefB, const Standard_Real ACoefC, const Standard_Real ACoefD) { - - MyCPlane.WsId = -1; - MyCPlane.ViewId = 0; /* not used */ - - MyCPlane.CoefA = float (ACoefA); - MyCPlane.CoefB = float (ACoefB); - MyCPlane.CoefC = float (ACoefC); - MyCPlane.CoefD = float (ACoefD); - - MyCPlane.PlaneId = - Graphic3d_GraphicDriver::Plane (MyCPlane, Standard_False); - -} - -void Visual3d_ClipPlane::SetPlane (const Standard_Real ACoefA, const Standard_Real ACoefB, const Standard_Real ACoefC, const Standard_Real ACoefD) { - - MyCPlane.CoefA = float (ACoefA); - MyCPlane.CoefB = float (ACoefB); - MyCPlane.CoefC = float (ACoefC); - MyCPlane.CoefD = float (ACoefD); - - MyCPlane.PlaneId = - Graphic3d_GraphicDriver::Plane (MyCPlane, Standard_True); - -} - -void Visual3d_ClipPlane::Plane (Standard_Real& ACoefA, Standard_Real& ACoefB, Standard_Real& ACoefC, Standard_Real& ACoefD) const { - - ACoefA = Standard_Real (MyCPlane.CoefA); - ACoefB = Standard_Real (MyCPlane.CoefB); - ACoefC = Standard_Real (MyCPlane.CoefC); - ACoefD = Standard_Real (MyCPlane.CoefD); - -} - -Standard_Integer Visual3d_ClipPlane::Limit () { - -#ifdef GER61454 - return 4; // Obsolete method, calls instead myView->PlaneLimit() -#else - // Old method, replaced by GraphicDriver::InquirePlaneLimit () - return 0; -#endif -} - -Standard_Integer Visual3d_ClipPlane::Identification () const { - - return (Standard_Integer (MyCPlane.PlaneId)); - -} diff --git a/src/Visual3d/Visual3d_ContextView.cdl b/src/Visual3d/Visual3d_ContextView.cdl index 29846a4638..3b0f33c6d8 100755 --- a/src/Visual3d/Visual3d_ContextView.cdl +++ b/src/Visual3d/Visual3d_ContextView.cdl @@ -39,14 +39,14 @@ class ContextView from Visual3d uses SequenceOfAddress from TColStd, - ClipPlane from Visual3d, Light from Visual3d, HSetOfLight from Visual3d, - HSetOfClipPlane from Visual3d, + TypeOfModel from Visual3d, TypeOfVisualization from Visual3d, TypeOfSurfaceDetail from Visual3d, - TextureEnv from Graphic3d + TextureEnv from Graphic3d, + SetOfHClipPlane from Graphic3d raises @@ -147,19 +147,14 @@ is -- Clip Plane --------------------------------------------------- - SetClipPlaneOn ( me : in out; - AClipPlane : ClipPlane from Visual3d ) - is static; - ---Level: Internal - ---Purpose: Activates the clipping plane - ---Category: Methods to modify the class definition + SetClipPlanes (me : in out; thePlanes : SetOfHClipPlane from Graphic3d); + ---Purpose: Set list of clip planes to the view context. + -- @param thePlanes [in] the clip planes to set. - SetClipPlaneOff ( me : in out; - AClipPlane : ClipPlane from Visual3d ) - is static; - ---Level: Internal - ---Purpose: Deactivates the clipping plane - ---Category: Methods to modify the class definition + GetClipPlanes (me) returns SetOfHClipPlane from Graphic3d; + ---C++: return const& + ---Purpose: Get clip planes. + -- @return sequence of clip planes. --------------------------------------------------- -- Category: Methods to modify the class definition @@ -285,29 +280,6 @@ is -- Category: Inquire methods ---------------------------- - ActivatedClipPlanes ( me ) - returns HSetOfClipPlane from Visual3d - is static; - ---Level: Internal - ---Purpose: Returns the group of active clipping planes - -- in the view of context . - ---Category: Inquire methods - - NumberOfActivatedClipPlanes ( me ) - returns Integer from Standard - is static; - ---Level: Internal - ---Purpose: Returns the number of active clipping planes - -- in the view of context . - ---Category: Inquire methods - - ActivatedClipPlane ( me; - AnIndex : Integer from Standard ) - returns ClipPlane from Visual3d - is static; - ---Level: Internal - ---Category: Inquire methods - ActivatedLights ( me ) returns HSetOfLight from Visual3d is static; @@ -465,11 +437,9 @@ fields -- the light sources activated MyLights : SequenceOfAddress from TColStd; - -- the clipping planes activated - MyClipPlanes : SequenceOfAddress from TColStd; - - MyTextureEnv : TextureEnv from Graphic3d; MySurfaceDetail : TypeOfSurfaceDetail from Visual3d; + myClipPlanes : SetOfHClipPlane from Graphic3d; + end ContextView; diff --git a/src/Visual3d/Visual3d_ContextView.cxx b/src/Visual3d/Visual3d_ContextView.cxx index bdddc2f9f1..370ec549ba 100755 --- a/src/Visual3d/Visual3d_ContextView.cxx +++ b/src/Visual3d/Visual3d_ContextView.cxx @@ -60,9 +60,9 @@ MyDepthCueingBackPlane (Standard_ShortReal (0.0)), MyModel (Visual3d_TOM_NONE), MyVisual (Visual3d_TOV_WIREFRAME), MyLights (), -MyClipPlanes (), MyTextureEnv(), -MySurfaceDetail(Visual3d_TOD_NONE) +MySurfaceDetail(Visual3d_TOD_NONE), +myClipPlanes() { } @@ -311,65 +311,6 @@ Handle(Visual3d_Light) Visual3d_ContextView::ActivatedLight (const Standard_Inte } -void Visual3d_ContextView::SetClipPlaneOn (const Handle(Visual3d_ClipPlane)& AClipPlane) { - -Standard_Integer LengthC = MyClipPlanes.Length (); -Standard_Integer indexC = 0; - - // Find plane in the - // sequence of already active planes - for (Standard_Integer i=1; i<=LengthC && indexC==0; i++) - if ((void *) (MyClipPlanes.Value (i)) == - (void *) (AClipPlane.operator->())) indexC = i; - - // This is the activation of a new plane - if (indexC == 0) - MyClipPlanes.Append ((void *) AClipPlane.operator->()); - -} - -void Visual3d_ContextView::SetClipPlaneOff (const Handle(Visual3d_ClipPlane)& AClipPlane) { - -Standard_Integer LengthC = MyClipPlanes.Length (); -Standard_Integer indexC = 0; - - // Find plane in the - // sequence of already active planes - for (Standard_Integer i=1; i<=LengthC && indexC==0; i++) - if ((void *) (MyClipPlanes.Value (i)) == - (void *) (AClipPlane.operator->())) indexC = i; - - // This is an active plane - if (indexC != 0) MyClipPlanes.Remove (indexC); - -} - -Handle(Visual3d_HSetOfClipPlane) Visual3d_ContextView::ActivatedClipPlanes () const { - -Handle(Visual3d_HSetOfClipPlane) SG = new Visual3d_HSetOfClipPlane (); -Standard_Integer Length = MyClipPlanes.Length (); - - for (Standard_Integer i=1; i<=Length; i++) - SG->Add ((Visual3d_ClipPlane *) (MyClipPlanes.Value (i))); - - return (SG); - -} - -Standard_Integer Visual3d_ContextView::NumberOfActivatedClipPlanes () const { - -Standard_Integer Length = MyClipPlanes.Length (); - - return (Length); - -} - -Handle(Visual3d_ClipPlane) Visual3d_ContextView::ActivatedClipPlane (const Standard_Integer AnIndex) const { - - return (Visual3d_ClipPlane *) (MyClipPlanes.Value (AnIndex)); -} - - void Visual3d_ContextView::SetSurfaceDetail(const Visual3d_TypeOfSurfaceDetail TOSD) { MySurfaceDetail = TOSD; @@ -392,3 +333,13 @@ Visual3d_TypeOfSurfaceDetail Visual3d_ContextView::SurfaceDetail() const { return MySurfaceDetail; } + +void Visual3d_ContextView::SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes) +{ + myClipPlanes = thePlanes; +} + +const Graphic3d_SetOfHClipPlane& Visual3d_ContextView::GetClipPlanes() const +{ + return myClipPlanes; +} diff --git a/src/Visual3d/Visual3d_View.cdl b/src/Visual3d/Visual3d_View.cdl index fb6b0a6546..2515259943 100755 --- a/src/Visual3d/Visual3d_View.cdl +++ b/src/Visual3d/Visual3d_View.cdl @@ -90,10 +90,8 @@ uses MapOfStructure from Graphic3d, ContextView from Visual3d, - ClipPlane from Visual3d, Layer from Visual3d, Light from Visual3d, - SetOfClipPlane from Visual3d, SetOfLight from Visual3d, TypeOfAnswer from Visual3d, ViewMapping from Visual3d, diff --git a/src/Visual3d/Visual3d_View.cxx b/src/Visual3d/Visual3d_View.cxx index 26685b1bad..960f7f723b 100755 --- a/src/Visual3d/Visual3d_View.cxx +++ b/src/Visual3d/Visual3d_View.cxx @@ -147,11 +147,6 @@ #include #include -#include -#include -#include -#include - #include #include @@ -198,10 +193,6 @@ Standard_Integer i, j; MyCView.DefWindow.IsDefined = 0; MyCView.Context.NbActiveLight = 0; - MyCView.Context.NbActivePlane = 0; -#ifdef GER61454 - MyCView.Context.ActivePlane = NULL; -#endif for (i=0; i<=3; i++) for (j=0; j<=3; j++) @@ -311,10 +302,6 @@ Standard_Integer i, j; MyCView.DefWindow.IsDefined = 0; MyCView.Context.NbActiveLight = 0; - MyCView.Context.NbActivePlane = 0; -#ifdef GER61454 - MyCView.Context.ActivePlane = NULL; -#endif for (i=0; i<=3; i++) for (j=0; j<=3; j++) @@ -863,64 +850,14 @@ Visual3d_TypeOfLightSource LightType=Visual3d_TOLS_AMBIENT; } -void Visual3d_View::UpdatePlanes () { - -Standard_Integer i, j; -CALL_DEF_PLANE *planes=NULL; - - i = MyContext.NumberOfActivatedClipPlanes (); - j = MyGraphicDriver->InquirePlaneLimit (); - MyCView.Context.NbActivePlane = (i > j ? j : i); - - if (MyCView.Context.NbActivePlane > 0) { - - // Dynamic Allocation -#ifdef GER61454 //Keep the plane address for the next Update ! - if( !MyCView.Context.ActivePlane ) - MyCView.Context.ActivePlane = new CALL_DEF_PLANE [j]; - planes = MyCView.Context.ActivePlane; -#else - planes = new CALL_DEF_PLANE [MyCView.Context.NbActivePlane]; - - MyCView.Context.ActivePlane = planes; -#endif -Standard_Real A, B, C, D; - - // Parcing of clipping planes - for (j=0; jIdentification ()); - - (MyContext.ActivatedClipPlane (j+1))->Plane (A, B, C, D); - planes[j].CoefA = float (A); - planes[j].CoefB = float (B); - planes[j].CoefC = float (C); - planes[j].CoefD = float (D); - } - - } - - // Management of planes of clipping model - if (! IsDeleted ()) - if (IsDefined ()) - MyGraphicDriver->SetPlane (MyCView); - - // Dynamic allocation -#ifdef GER61454 - if ( MyCView.Context.ActivePlane && (MyCView.Context.NbActivePlane == 0) - ) { - delete [] MyCView.Context.ActivePlane; - MyCView.Context.ActivePlane = NULL; - } -#else - if (MyCView.Context.NbActivePlane > 0) delete [] planes; -#endif +void Visual3d_View::UpdatePlanes() +{ + MyCView.Context.ClipPlanes = MyContext.GetClipPlanes(); + + if (IsDeleted() || !IsDefined()) + return; + MyGraphicDriver->SetClipPlanes (MyCView); } void Visual3d_View::SetBackground (const Aspect_Background& ABack) { diff --git a/tests/bugs/vis/bug22906 b/tests/bugs/vis/bug22906 index ee1b7348c4..81d7a905ce 100755 --- a/tests/bugs/vis/bug22906 +++ b/tests/bugs/vis/bug22906 @@ -29,7 +29,9 @@ set Color1 [QAGetPixelColor ${x1} ${y1}] set Color2 [QAGetPixelColor ${x2} ${y2}] set Color3 [QAGetPixelColor ${x3} ${y3}] set Color4 [QAGetPixelColor ${x4} ${y4}] -vclipplane 0.1 0 0 1 0 0 +vclipplane create pln1 +vclipplane change pln1 equation 1 0 0 -0.1 +vclipplane set pln1 view Driver1/Viewer1/View1 box b 100 100 100 vdisplay b vsetdispmode 1