From 6635afb0c0035add53f6b5641bce65717fa06d7d Mon Sep 17 00:00:00 2001 From: kgv Date: Tue, 9 Sep 2014 17:21:22 +0400 Subject: [PATCH] 0025129: Visualization - add interactive object for Points Cloud objects New class AIS_PointCloud for displaying point sets. Update Graphic3d_ArrayOfPoints, OpenGl_PrimitiveArray and OpenGl_VertexBuffer classes to be able to use normals for points. Add Draw Harness command vpointcloud. --- src/AIS/AIS.cdl | 3 +- src/AIS/AIS_PointCloud.cxx | 461 ++++++++++++++++++ src/AIS/AIS_PointCloud.hxx | 126 +++++ src/AIS/AIS_Shape.cdl | 4 +- src/AIS/AIS_Shape.cxx | 28 +- src/AIS/AIS_TexturedShape.cxx | 2 +- src/AIS/FILES | 2 + src/Graphic3d/Graphic3d_ArrayOfPoints.cdl | 6 +- src/Graphic3d/Graphic3d_ArrayOfPoints.cxx | 7 +- src/OpenGl/OpenGl_PrimitiveArray.cxx | 22 +- .../StdPrs_WFDeflectionRestrictedFace.cdl | 10 +- .../StdPrs_WFDeflectionRestrictedFace.cxx | 45 ++ src/ViewerTest/ViewerTest_ObjectCommands.cxx | 144 ++++++ 13 files changed, 813 insertions(+), 47 deletions(-) create mode 100644 src/AIS/AIS_PointCloud.cxx create mode 100644 src/AIS/AIS_PointCloud.hxx diff --git a/src/AIS/AIS.cdl b/src/AIS/AIS.cdl index 75098fd7d4..3756366f4e 100644 --- a/src/AIS/AIS.cdl +++ b/src/AIS/AIS.cdl @@ -367,7 +367,8 @@ is ---Category: General Objects class ConnectedInteractive; --signature 0 - class MultipleConnectedInteractive; --signature 1 + class MultipleConnectedInteractive; --signature 1 + imported PointCloud; ---Category: DIMENSIONS AND RELATIONS diff --git a/src/AIS/AIS_PointCloud.cxx b/src/AIS/AIS_PointCloud.cxx new file mode 100644 index 0000000000..8b01a1b5ca --- /dev/null +++ b/src/AIS/AIS_PointCloud.cxx @@ -0,0 +1,461 @@ +// Created on: 2014-08-13 +// Created by: Maxim GLIBIN +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_HANDLE (AIS_PointCloud, AIS_InteractiveObject) +IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject) + +//================================================== +// Function: AIS_PointCloud +// Purpose : Constructor +//================================================== +AIS_PointCloud::AIS_PointCloud() +: mySelEntity (AIS_PointCloud::SE_BndBox) +{ + SetDisplayMode (AIS_PointCloud::DM_Points); + SetHilightMode (AIS_PointCloud::DM_BndBox); +} + +//======================================================================= +//function : GetPoints +//purpose : +//======================================================================= +const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const +{ + return myPoints; +} + +//======================================================================= +//function : GetBoundingBox +//purpose : +//======================================================================= +Bnd_Box AIS_PointCloud::GetBoundingBox() const +{ + return myBndBox; +} + +//! Auxiliary method +static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints) +{ + Bnd_Box aBndBox; + if (thePoints.IsNull()) + { + return aBndBox; + } + + const Standard_Integer aNbVertices = thePoints->VertexNumber(); + for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter) + { + aBndBox.Add (thePoints->Vertice (aVertIter)); + } + return aBndBox; +} + +//======================================================================= +//function : SetPoints +//purpose : +//======================================================================= +void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints) +{ + myPoints = thePoints; + myBndBox = getBoundingBox (thePoints); +} + +//======================================================================= +//function : SetPoints +//purpose : +//======================================================================= +void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords, + const Handle(Quantity_HArray1OfColor)& theColors, + const Handle(TColgp_HArray1OfDir)& theNormals) +{ + myPoints.Nullify(); + myBndBox.SetVoid(); + if (theCoords.IsNull()) + { + return; + } + + const Standard_Integer aNbPoints = theCoords->Length(); + if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints) + || (!theColors.IsNull() && theColors->Length() != aNbPoints)) + { + // invalid input + return; + } + + const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints; + const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints; + + const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0; + const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0; + + myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals); + for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter) + { + myPoints->AddVertex (theCoords->Value (aPntIter)); + if (hasColors) + { + myPoints->SetVertexColor (myPoints->VertexNumber(), + theColors->Value (aPntIter + aDiffColors)); + } + if (hasNormals) + { + myPoints->SetVertexNormal (myPoints->VertexNumber(), + theNormals->Value (aPntIter + aDiffNormals)); + } + } + myBndBox = getBoundingBox (myPoints); +} + +//======================================================================= +//function : SetColor +//purpose : +//======================================================================= +void AIS_PointCloud::SetColor (const Quantity_NameOfColor theColor) +{ + SetColor (Quantity_Color (theColor)); +} + +//======================================================================= +//function : SetColor +//purpose : +//======================================================================= +void AIS_PointCloud::SetColor (const Quantity_Color& theColor) +{ + if (!myDrawer->HasPointAspect()) + { + myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, theColor, 1.0)); + *myDrawer->PointAspect()->Aspect() = *myDrawer->Link()->PointAspect()->Aspect(); + } + if (!myDrawer->HasShadingAspect()) + { + myDrawer->SetShadingAspect (new Prs3d_ShadingAspect()); + *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect(); + } + + // Override color + myDrawer->ShadingAspect()->SetColor (theColor); + myDrawer->PointAspect() ->SetColor (theColor); + + hasOwnColor = Standard_True; + myOwnColor = theColor; + + const PrsMgr_Presentations& aPrsList = Presentations(); + Handle(Graphic3d_AspectMarker3d) aPointAspect = myDrawer->PointAspect()->Aspect(); + Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect(); + for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt) + { + const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt); + const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation(); + + // Set aspects for presentation + aPrs->SetPrimitivesAspect (aPointAspect); + aPrs->SetPrimitivesAspect (anAreaAspect); + + // Go through all groups to change color for all primitives + for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next()) + { + const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value(); + if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER)) + { + aGroup->SetGroupPrimitivesAspect (aPointAspect); + } + if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA)) + { + aGroup->SetGroupPrimitivesAspect (anAreaAspect); + } + } + } +} + +//======================================================================= +//function : UnsetColor +//purpose : +//======================================================================= +void AIS_PointCloud::UnsetColor() +{ + if (!HasColor()) + { + return; + } + hasOwnColor = Standard_False; + + if (!HasWidth()) + { + myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)()); + } + else + { + Quantity_Color aColor; + Aspect_TypeOfMarker aType = Aspect_TOM_POINT; + Standard_Real aScale = 1.0; + myDrawer->Link()->PointAspect()->Aspect()->Values (aColor, aType, aScale); + myDrawer->PointAspect()->SetColor (aColor); + } + + if (HasMaterial() + || IsTransparent()) + { + Graphic3d_MaterialAspect aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link()); + if (HasMaterial()) + { + Quantity_Color aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel); + aMat.SetColor (aColor); + } + if (IsTransparent()) + { + Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel); + aMat.SetTransparency (aTransp); + } + myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel); + } + else + { + myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)()); + } + myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)()); + + // modify shading presentation without re-computation + const PrsMgr_Presentations& aPrsList = Presentations(); + Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect(); + Handle(Graphic3d_AspectMarker3d) aMarkerAsp = myDrawer->Link()->PointAspect()->Aspect(); + for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt) + { + const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt); + if (aPrsModed.Mode() != AIS_PointCloud::DM_Points) + { + continue; + } + + const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation(); + aPrs->SetPrimitivesAspect (anAreaAsp); + aPrs->SetPrimitivesAspect (aMarkerAsp); + for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next()) + { + const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value(); + + // Check if aspect of given type is set for the group, + // because setting aspect for group with no already set aspect + // can lead to loss of presentation data + if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA)) + { + aGroup->SetGroupPrimitivesAspect (anAreaAsp); + } + if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER)) + { + aGroup->SetGroupPrimitivesAspect (aMarkerAsp); + } + } + } +} + +//======================================================================= +//function : SetMaterial +//purpose : +//======================================================================= +void AIS_PointCloud::SetMaterial (const Graphic3d_NameOfMaterial theMatName) +{ + SetMaterial (Graphic3d_MaterialAspect (theMatName)); +} + +//======================================================================= +//function : SetMaterial +//purpose : +//======================================================================= +void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat) +{ + if (!myDrawer->HasShadingAspect()) + { + myDrawer->SetShadingAspect (new Prs3d_ShadingAspect()); + *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect(); + } + hasOwnMaterial = Standard_True; + + myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel); + if (HasColor()) + { + myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel); + } + myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel); + + // modify shading presentation without re-computation + const PrsMgr_Presentations& aPrsList = Presentations(); + Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect(); + for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt) + { + const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt); + if (aPrsModed.Mode() != AIS_PointCloud::DM_Points) + { + continue; + } + + const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation(); + aPrs->SetPrimitivesAspect (anAreaAsp); + for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next()) + { + const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value(); + if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA)) + { + aGroup->SetGroupPrimitivesAspect (anAreaAsp); + } + } + } +} + +//======================================================================= +//function : UnsetMaterial +//purpose : +//======================================================================= +void AIS_PointCloud::UnsetMaterial() +{ + if (!HasMaterial()) + { + return; + } + + if (HasColor() + || IsTransparent()) + { + myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel), + myCurrentFacingModel); + if (HasColor()) + { + myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel); + myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel); + } + } + else + { + myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)()); + } + hasOwnMaterial = Standard_False; + + // modify shading presentation without re-computation + const PrsMgr_Presentations& aPrsList = Presentations(); + Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect(); + for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt) + { + const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt); + if (aPrsModed.Mode() != AIS_PointCloud::DM_Points) + { + continue; + } + + const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation(); + aPrs->SetPrimitivesAspect (anAreaAsp); + for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next()) + { + const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value(); + if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA)) + { + aGroup->SetGroupPrimitivesAspect (anAreaAsp); + } + } + } +} + +//======================================================================= +//function : Compute +//purpose : +//======================================================================= +void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/, + const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theMode) +{ + thePrs->Clear(); + switch (theMode) + { + case AIS_PointCloud::DM_Points: + { + const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints(); + if (aPoints.IsNull()) + { + return; + } + + Handle(Graphic3d_AspectMarker3d) aMarkerAspect = myDrawer->PointAspect()->Aspect(); + if (!myDrawer->HasPointAspect()) + { + aMarkerAspect->SetType (Aspect_TOM_POINT); + } + + Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs); + aGroup->SetGroupPrimitivesAspect (aMarkerAspect); + aGroup->AddPrimitiveArray (aPoints); + break; + } + case AIS_PointCloud::DM_BndBox: + { + Bnd_Box aBndBox = GetBoundingBox(); + if (aBndBox.IsVoid()) + { + return; + } + + StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, aBndBox, myDrawer); + break; + } + } +} + +//======================================================================= +//function : ComputeSelection +//purpose : +//======================================================================= +void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, + const Standard_Integer /*theMode*/) +{ + switch (mySelEntity) + { + case AIS_PointCloud::SE_DISABLED: + { + return; + } + case AIS_PointCloud::SE_BndBox: + { + Bnd_Box aBndBox = GetBoundingBox(); + if (aBndBox.IsVoid()) + { + return; + } + + Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this); + Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox); + theSelection->Add (aSensBox); + return; + } + } +} diff --git a/src/AIS/AIS_PointCloud.hxx b/src/AIS/AIS_PointCloud.hxx new file mode 100644 index 0000000000..3f06ef2e6a --- /dev/null +++ b/src/AIS/AIS_PointCloud.hxx @@ -0,0 +1,126 @@ +// Created on: 2014-08-13 +// Created by: Maxim GLIBIN +// Copyright (c) 2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _AIS_PointCloud_HeaderFile +#define _AIS_PointCloud_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DEFINE_STANDARD_HANDLE(AIS_PointCloud, AIS_InteractiveObject) + +//! Interactive object for set of points. +//! Selection services are not provided by this class. +class AIS_PointCloud : public AIS_InteractiveObject +{ + +public: + + //! Display modes supported by this Point Cloud object + enum DisplayMode + { + DM_Points = 0, //!< display as normal points, default presentation + DM_BndBox = 2 //!< display as bounding box, default for highlighting + }; + + //! Entity to use for selection. + //! Default - select by bounding box. + enum SelectionEntity + { + SE_DISABLED = 0, //!< do not create selection entity - object will be unselectable from 3D viewer, but can be highlighted from application + SE_BndBox = 2 //!< create bounding box selection entity + }; + +public: + + //! Empty constructor + Standard_EXPORT AIS_PointCloud(); + + //! Sets the points from array of points. + //! Method will not copy the input data - array will be stored as handle. + //! @param thePoints [in] the array of points + Standard_EXPORT virtual void SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints); + + //! Sets the points with optional colors. + //! The input data will be copied into internal buffer. + //! @param theCoords [in] the array of coordinates + //! @param theColors [in] optional array of colors + //! @param theNormals [in] optional array of normals + Standard_EXPORT virtual void SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords, + const Handle(Quantity_HArray1OfColor)& theColors = NULL, + const Handle(TColgp_HArray1OfDir)& theNormals = NULL); + +public: + + //! Get the points array. + //! Method might be overridden to fill in points array dynamically from application data structures. + //! @return the array of points + Standard_EXPORT virtual const Handle(Graphic3d_ArrayOfPoints) GetPoints() const; + + //! Get bounding box for presentation. + Standard_EXPORT virtual Bnd_Box GetBoundingBox() const; + +public: + + //! Setup custom color. Affects presentation only when no per-point color attribute has been assigned. + Standard_EXPORT virtual void SetColor (const Quantity_NameOfColor theColor); + + //! Setup custom color. Affects presentation only when no per-point color attribute has been assigned. + Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor); + + //! Restore default color. + Standard_EXPORT virtual void UnsetColor(); + + //! Setup custom material. Affects presentation only when normals are defined. + Standard_EXPORT virtual void SetMaterial (const Graphic3d_NameOfMaterial theMatName); + + //! Setup custom material. Affects presentation only when normals are defined. + Standard_EXPORT virtual void SetMaterial (const Graphic3d_MaterialAspect& theMat); + + //! Restore default material. + Standard_EXPORT virtual void UnsetMaterial(); + +protected: + + //! Prepare presentation for this object. + Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr, + const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theMode); + + //! Prepare selection for this object. + Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, + const Standard_Integer theMode); + +private: + + Handle(Graphic3d_ArrayOfPoints) myPoints; //!< points array for presentation + Bnd_Box myBndBox; //!< bounding box for presentation + SelectionEntity mySelEntity; //!< selection entity + +public: + + DEFINE_STANDARD_RTTI(AIS_PointCloud) + +}; + +#endif // _AIS_PointCloud_HeaderFile diff --git a/src/AIS/AIS_Shape.cdl b/src/AIS/AIS_Shape.cdl index a7990c9e9e..16c8c1101f 100644 --- a/src/AIS/AIS_Shape.cdl +++ b/src/AIS/AIS_Shape.cdl @@ -294,11 +294,11 @@ uses GetDeflection(myclass; aShape : Shape from TopoDS; aDrawer : Drawer from Prs3d) returns Real from Standard; - + DisplayBox(myclass; aPrs : Presentation from Prs3d; aBox : Box from Bnd; aDrawer : Drawer from Prs3d) is protected; - + setColor (me; theDrawer : Drawer from AIS; theColor : Color from Quantity) diff --git a/src/AIS/AIS_Shape.cxx b/src/AIS/AIS_Shape.cxx index 68088dd45e..bc6db38c7f 100644 --- a/src/AIS/AIS_Shape.cxx +++ b/src/AIS/AIS_Shape.cxx @@ -98,31 +98,7 @@ void AIS_Shape::DisplayBox(const Handle(Prs3d_Presentation)& aPrs, const Bnd_Box& B, const Handle(Prs3d_Drawer)& aDrawer) { - static const Standard_Integer Indx[][3] = - { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 }, - { 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 }, - { 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, - { 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } }; - - if ( B.IsVoid() ) - return; // nothing to show - - Standard_Real X[2],Y[2],Z[2]; - B.Get(X[0], Y[0], Z[0], X[1], Y[1], Z[1]); - - Handle(Graphic3d_Group) G = Prs3d_Root::CurrentGroup(aPrs); - Quantity_Color Q; - Aspect_TypeOfLine A; - Standard_Real W; - aDrawer->LineAspect()->Aspect()->Values(Q,A,W); - - G->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d(Q,Aspect_TOL_DOTDASH,W)); - - Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16); - Standard_Integer i(0); - for(;i<16;i++) - aPolyline->AddVertex(X[Indx[i][0]],Y[Indx[i][1]],Z[Indx[i][2]]); - G->AddPrimitiveArray(aPolyline); + return StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, B, aDrawer); } static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode) @@ -255,7 +231,7 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat { // bounding box if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); - else DisplayBox(aPrs,BoundingBox(),myDrawer); + else StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, BoundingBox(), myDrawer); } } // end switch aPrs->ReCompute(); // for hidden line recomputation if necessary... diff --git a/src/AIS/AIS_TexturedShape.cxx b/src/AIS/AIS_TexturedShape.cxx index 27b8fac864..6eafb227ff 100644 --- a/src/AIS/AIS_TexturedShape.cxx +++ b/src/AIS/AIS_TexturedShape.cxx @@ -325,7 +325,7 @@ void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*t } else { - AIS_Shape::DisplayBox (thePrs, BoundingBox(), myDrawer); + StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, BoundingBox(), myDrawer); } break; } diff --git a/src/AIS/FILES b/src/AIS/FILES index 9b7b40d1f5..2f3c30c8e9 100755 --- a/src/AIS/FILES +++ b/src/AIS/FILES @@ -21,3 +21,5 @@ AIS_DiameterDimension.hxx AIS_DiameterDimension.cxx AIS_RadiusDimension.hxx AIS_RadiusDimension.cxx +AIS_PointCloud.hxx +AIS_PointCloud.cxx diff --git a/src/Graphic3d/Graphic3d_ArrayOfPoints.cdl b/src/Graphic3d/Graphic3d_ArrayOfPoints.cdl index 665d008800..9573b5f909 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPoints.cdl +++ b/src/Graphic3d/Graphic3d_ArrayOfPoints.cdl @@ -18,11 +18,13 @@ is -- constructor Create (maxVertexs: Integer from Standard; - hasVColors: Boolean from Standard = Standard_False) - returns mutable ArrayOfPoints from Graphic3d; + hasVColors: Boolean from Standard = Standard_False; + hasVNormals: Boolean from Standard = Standard_False) + returns ArrayOfPoints from Graphic3d; ---Purpose: Creates an array of points, -- a single pixel point is drawn at each vertex. -- The array must be filled using the AddVertex(Point) method. -- When is TRUE , you must use only AddVertex(Point,Color) method. + -- When is TRUE , you must use only AddVertex(Point,Normal) method. end; diff --git a/src/Graphic3d/Graphic3d_ArrayOfPoints.cxx b/src/Graphic3d/Graphic3d_ArrayOfPoints.cxx index 253838b62a..3909b0638e 100644 --- a/src/Graphic3d/Graphic3d_ArrayOfPoints.cxx +++ b/src/Graphic3d/Graphic3d_ArrayOfPoints.cxx @@ -14,7 +14,8 @@ #include -Graphic3d_ArrayOfPoints :: Graphic3d_ArrayOfPoints (const Standard_Integer maxVertexs, - const Standard_Boolean hasVColors) -: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, maxVertexs, 0, 0, Standard_False, hasVColors, Standard_False, Standard_False, Standard_False) +Graphic3d_ArrayOfPoints::Graphic3d_ArrayOfPoints (const Standard_Integer theMaxVertexs, + const Standard_Boolean theHasVColors, + const Standard_Boolean theHasVNormals) +: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, theMaxVertexs, 0, 0, theHasVNormals, theHasVColors, Standard_False, Standard_False) {} diff --git a/src/OpenGl/OpenGl_PrimitiveArray.cxx b/src/OpenGl/OpenGl_PrimitiveArray.cxx index b8bbcd5aa8..fae40e7f11 100755 --- a/src/OpenGl/OpenGl_PrimitiveArray.cxx +++ b/src/OpenGl/OpenGl_PrimitiveArray.cxx @@ -231,14 +231,6 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel, pvc = NULL; } - // Sometimes the GL_LIGHTING mode is activated here - // without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary - // to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism* - if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP) - glDisable (GL_LIGHTING); - else - glEnable (GL_LIGHTING); - if (!toDrawVbo()) { if (myPArray->vertices != NULL) @@ -246,10 +238,15 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel, glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices glEnableClientState (GL_VERTEX_ARRAY); } - if (myPArray->vnormals != NULL) + if (myPArray->vnormals != NULL && theLightingModel != 0) { glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals glEnableClientState (GL_NORMAL_ARRAY); + glEnable (GL_LIGHTING); + } + else + { + glDisable (GL_LIGHTING); } if (myPArray->vtexels != NULL) { @@ -269,9 +266,14 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel, { // Bindings concrete pointer in accordance with VBO buffer myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY); - if (!myVbos[VBOVnormals].IsNull()) + if (!myVbos[VBOVnormals].IsNull() && theLightingModel != 0) { myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY); + glEnable (GL_LIGHTING); + } + else + { + glDisable (GL_LIGHTING); } if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) { diff --git a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cdl b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cdl index 8860cdc102..a99eebf650 100644 --- a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cdl +++ b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cdl @@ -24,13 +24,13 @@ inherits Root from Prs3d -- a deflection on them. uses + Box from Bnd, HSurface from BRepAdaptor, Presentation from Prs3d, Drawer from Prs3d, Length from Quantity, NListOfSequenceOfPnt from Prs3d - is Add(myclass; aPresentation: Presentation from Prs3d; aFace : HSurface from BRepAdaptor; @@ -108,7 +108,13 @@ is -- as a geometric surface. -- Curves give a sequence of face curves, it is used if the PrimitiveArray -- visualization approach is activated (it is activated by default). - + + AddBox (myclass; + thePrs : Presentation from Prs3d; + theBndBox : Box from Bnd; + theDrawer : Drawer from Prs3d); + ---Purpose: Adds box as polyline to the presentation object + Match(myclass; X,Y,Z : Length from Quantity; aDistance: Length from Quantity; aFace : HSurface from BRepAdaptor; diff --git a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx index 53422e24f2..f196df82c2 100644 --- a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx +++ b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx @@ -17,6 +17,8 @@ #include #include +#include +#include #include #include #include @@ -623,3 +625,46 @@ Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso aDrawer->UIsoAspect()->Number(), aDrawer->VIsoAspect()->Number()); } + +namespace +{ + static const Standard_Integer THE_INDICES[][3] = + { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 }, + { 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 }, + { 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, + { 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } }; +} + +//======================================================================= +//function : AddBox +//purpose : +//======================================================================= +void StdPrs_WFDeflectionRestrictedFace::AddBox (const Handle(Prs3d_Presentation)& thePrs, + const Bnd_Box& theBndBox, + const Handle(Prs3d_Drawer)& theDrawer) +{ + if (theBndBox.IsVoid()) + { + return; + } + + Standard_Real X[2], Y[2], Z[2]; + theBndBox.Get (X[0], Y[0], Z[0], X[1], Y[1], Z[1]); + + Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs); + Quantity_Color aColor; + Aspect_TypeOfLine aDummyLineType; + Standard_Real aWidth = 1.0; + theDrawer->LineAspect()->Aspect()->Values (aColor, aDummyLineType, aWidth); + + aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (aColor, Aspect_TOL_DOTDASH, aWidth)); + + Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16); + for(Standard_Integer aVertIter = 0; aVertIter < 16; ++aVertIter) + { + aPolyline->AddVertex (X[THE_INDICES[aVertIter][0]], + Y[THE_INDICES[aVertIter][1]], + Z[THE_INDICES[aVertIter][2]]); + } + aGroup->AddPrimitiveArray (aPolyline); +} diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 833dd02db8..346cc65c5d 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -5028,6 +5029,140 @@ static int VFont (Draw_Interpretor& theDI, return 0; } +//======================================================================= +//function : VPointCloud +//purpose : Create interactive object for arbitary set of points. +//======================================================================= +static Standard_Integer VPointCloud (Draw_Interpretor& theDI, + Standard_Integer theArgNum, + const char** theArgs) +{ + Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext(); + if (theArgNum < 3) + { + std::cout << "Error: wrong number of arguments! See usage:\n"; + theDI.PrintHelp (theArgs[0]); + return 1; + } + else if (anAISContext.IsNull()) + { + std::cerr << "Error: no active view!\n"; + return 1; + } + + Standard_Integer anArgIter = 1; + + Standard_CString aName = theArgs[anArgIter++]; + Standard_CString aShapeName = theArgs[anArgIter++]; + TopoDS_Shape aShape = DBRep::Get (aShapeName); + if (aShape.IsNull()) + { + std::cout << "Error: no shape with name '" << aShapeName << "' found\n"; + return 1; + } + + // parse arguments + Standard_Boolean toRandColors = Standard_False; + Standard_Boolean hasNormals = Standard_True; + for (; anArgIter < theArgNum; ++anArgIter) + { + Standard_CString anArg = theArgs[anArgIter]; + TCollection_AsciiString aFlag (anArg); + aFlag.LowerCase(); + if (aFlag == "-randcolors" + || aFlag == "-randcolor") + { + toRandColors = Standard_True; + } + else if (aFlag == "-normals" + || aFlag == "-normal") + { + hasNormals = Standard_True; + } + else if (aFlag == "-nonormals" + || aFlag == "-nonormal") + { + hasNormals = Standard_False; + } + else + { + std::cout << "Error: unknown argument '" << anArg << "'\n"; + return 1; + } + } + + // calculate number of points + TopLoc_Location aLocation; + Standard_Integer aNbPoints = 0; + for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current()); + Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation); + if (!aTriangulation.IsNull()) + { + aNbPoints += aTriangulation->NbNodes(); + } + } + if (aNbPoints < 3) + { + std::cout << "Error: shape should be triangulated!\n"; + return 1; + } + + VDisplayAISObject (aName, NULL); + Handle(Graphic3d_ArrayOfPoints) anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals); + for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current()); + Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation); + if (aTriangulation.IsNull()) + { + continue; + } + + const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); + const gp_Trsf& aTrsf = aLocation.Transformation(); + + // extract normals from nodes + TColgp_Array1OfDir aNormals (aNodes.Lower(), hasNormals ? aNodes.Upper() : aNodes.Lower()); + if (hasNormals) + { + Poly_Connect aPolyConnect (aTriangulation); + StdPrs_ToolShadedShape::Normal (aFace, aPolyConnect, aNormals); + } + + for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) + { + gp_Pnt aPoint = aNodes (aNodeIter); + if (!aLocation.IsIdentity()) + { + aPoint.Transform (aTrsf); + aNormals (aNodeIter).Transform (aTrsf); + } + + // add vertex into array of points + const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint); + if (toRandColors) + { + Quantity_Color aColor (360.0 * Standard_Real(anIndexOfPoint) / Standard_Real(aNbPoints), + 1.0, 0.5, Quantity_TOC_HLS); + anArrayPoints->SetVertexColor (anIndexOfPoint, aColor); + } + + if (hasNormals) + { + anArrayPoints->SetVertexNormal (anIndexOfPoint, aNormals (aNodeIter)); + } + } + } + + // set array of points in point cloud object + Handle(AIS_PointCloud) aPointCloud = new AIS_PointCloud(); + aPointCloud->SetPoints (anArrayPoints); + VDisplayAISObject (aName, aPointCloud); + return 0; +} + //======================================================================= //function : ObjectsCommands //purpose : @@ -5185,4 +5320,13 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) "vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined]]" "\n\t\t: [find fontName [regular,bold,italic,bolditalic=undefined]]", __FILE__, VFont, group); + + theCommands.Add ("vpointcloud", + "vpointcloud name shapename [-randColor] [-normals] [-noNormals]" + "\n\t\t: Create an interactive object for arbitary set of points" + "\n\t\t: from triangulated shape." + "\n\t\t: -randColor - generate random color per point" + "\n\t\t: -normals - generate normal per point (default)" + "\n\t\t: -noNormals - do not generate normal per point", + __FILE__, VPointCloud, group); }