diff --git a/src/AIS/AIS_PointCloud.cxx b/src/AIS/AIS_PointCloud.cxx index 6fda44896f..8b01a1b5ca 100644 --- a/src/AIS/AIS_PointCloud.cxx +++ b/src/AIS/AIS_PointCloud.cxx @@ -13,20 +13,28 @@ // 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 +#include +#include +#include -IMPLEMENT_STANDARD_HANDLE(AIS_PointCloud, AIS_InteractiveObject) +IMPLEMENT_STANDARD_HANDLE (AIS_PointCloud, AIS_InteractiveObject) IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject) //================================================== @@ -34,9 +42,45 @@ IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject) // Purpose : Constructor //================================================== AIS_PointCloud::AIS_PointCloud() -: AIS_InteractiveObject() +: mySelEntity (AIS_PointCloud::SE_BndBox) { - SetHilightMode (1); + 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; } //======================================================================= @@ -45,54 +89,60 @@ AIS_PointCloud::AIS_PointCloud() //======================================================================= void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints) { - myPoints.Nullify(); - - if (thePoints.IsNull()) - return; - myPoints = thePoints; + myBndBox = getBoundingBox (thePoints); } //======================================================================= //function : SetPoints -//purpose : +//purpose : //======================================================================= void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords, - const Handle(Quantity_HArray1OfColor)& theColors) + const Handle(Quantity_HArray1OfColor)& theColors, + const Handle(TColgp_HArray1OfDir)& theNormals) { myPoints.Nullify(); - + myBndBox.SetVoid(); if (theCoords.IsNull()) + { return; + } - Standard_Integer aNumPoints = theCoords->Length(); - Standard_Boolean hasColors = !theColors.IsNull() && aNumPoints == theColors->Length(); + const Standard_Integer aNbPoints = theCoords->Length(); + if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints) + || (!theColors.IsNull() && theColors->Length() != aNbPoints)) + { + // invalid input + return; + } - Standard_Integer aDiffColors = 0; - if (hasColors) - aDiffColors = theColors->Lower() - theCoords->Lower(); + const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints; + const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints; - myPoints = new Graphic3d_ArrayOfPoints (aNumPoints, hasColors); - for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); aPntIter++) + 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)); + { + myPoints->SetVertexColor (myPoints->VertexNumber(), + theColors->Value (aPntIter + aDiffColors)); + } + if (hasNormals) + { + myPoints->SetVertexNormal (myPoints->VertexNumber(), + theNormals->Value (aPntIter + aDiffNormals)); + } } -} - -//======================================================================= -//function : GetPoints -//purpose : -//======================================================================= -const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const -{ - return myPoints; + myBndBox = getBoundingBox (myPoints); } //======================================================================= //function : SetColor -//purpose : +//purpose : //======================================================================= void AIS_PointCloud::SetColor (const Quantity_NameOfColor theColor) { @@ -110,48 +160,302 @@ void AIS_PointCloud::SetColor (const Quantity_Color& theColor) myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, theColor, 1.0)); *myDrawer->PointAspect()->Aspect() = *myDrawer->Link()->PointAspect()->Aspect(); } - myDrawer->PointAspect()->SetColor (theColor); + 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; + 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 : +//purpose : //======================================================================= -void AIS_PointCloud::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/, - const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theMode) +void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/, + const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theMode) { - thePresentation->Clear(); - + thePrs->Clear(); switch (theMode) { - case 0: + case AIS_PointCloud::DM_Points: { const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints(); - if (aPoints.IsNull() || !aPoints->IsValid()) + 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 (thePresentation); + 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; } - default: - break; } } //======================================================================= //function : ComputeSelection -//purpose : +//purpose : //======================================================================= -void AIS_PointCloud::ComputeSelection(const Handle(SelectMgr_Selection)& /*theSelection*/, - const Standard_Integer /*theMode*/) +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 index 02603c0cc0..3f06ef2e6a 100644 --- a/src/AIS/AIS_PointCloud.hxx +++ b/src/AIS/AIS_PointCloud.hxx @@ -18,19 +18,16 @@ #include #include - +#include #include - #include - #include #include #include - #include #include -DEFINE_STANDARD_HANDLE (AIS_PointCloud, AIS_InteractiveObject) +DEFINE_STANDARD_HANDLE(AIS_PointCloud, AIS_InteractiveObject) //! Interactive object for set of points. //! Selection services are not provided by this class. @@ -39,46 +36,91 @@ class AIS_PointCloud : public AIS_InteractiveObject public: - //! Constructor - Standard_EXPORT AIS_PointCloud (); + //! 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 + }; - //! Sets the points from array of points. - //! @detailed This function allows to avoid data duplication. - //! @param thePoints [in] the array of points. - Standard_EXPORT virtual void SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints); - - //! Sets the points with optional colors. - //! @param theCoords [in] the array of coordinates. - //! @param theColors [in] optional array of colors. - Standard_EXPORT virtual void SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords, - const Handle(Quantity_HArray1OfColor)& theColors = NULL); - - //! Get the points. - //! @return the array of points. - Standard_EXPORT virtual const Handle(Graphic3d_ArrayOfPoints) GetPoints() const; - - //! Redefined method implemets the standard behavior. - Standard_EXPORT virtual void SetColor (const Quantity_NameOfColor theColor); - - //! Redefined method implemets the standard behavior. - Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor); + //! 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: - DEFINE_STANDARD_RTTI (AIS_PointCloud) + //! 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: - Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, - const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theMode = 0); + //! Prepare presentation for this object. + Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr, + const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theMode); - Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSelection, - 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; + 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/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 ebe642cdb3..346cc65c5d 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -5029,207 +5029,137 @@ static int VFont (Draw_Interpretor& theDI, return 0; } -//! Auxilarily function. -//! Create random float number in range from theMin to theMax. -static Standard_Real randomReal (const Standard_Real theMin, const Standard_Real theMax) -{ - return theMin + (theMax - theMin) * Standard_Real(rand()) / RAND_MAX; -} - //======================================================================= //function : VPointCloud //purpose : Create interactive object for arbitary set of points. //======================================================================= -static Standard_Integer VPointCloud (Draw_Interpretor& /*theDI*/, - Standard_Integer theArgNum, - const char** theArgs) +static Standard_Integer VPointCloud (Draw_Interpretor& theDI, + Standard_Integer theArgNum, + const char** theArgs) { - if (theArgNum < 2) + Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext(); + if (theArgNum < 3) { - std::cout << theArgs[0] << " error: wrong number of parameters. Type 'help " - << theArgs[0] << "' for more information." << std::endl; + std::cout << "Error: wrong number of arguments! See usage:\n"; + theDI.PrintHelp (theArgs[0]); return 1; } - - Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext(); - if (anAISContext.IsNull()) + else if (anAISContext.IsNull()) { - std::cout << "Call 'vinit' before!" << std::endl; + std::cerr << "Error: no active view!\n"; return 1; } Standard_Integer anArgIter = 1; - // Point cloud name - TCollection_AsciiString aName (theArgs[anArgIter++]); + 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; + } - // Default value - Standard_Integer aModeSetPoints = 0; - Standard_Integer aMarkerType = -1; - Quantity_NameOfColor aColorName = Quantity_NOC_GOLDENROD; - Standard_Real aScale = 1.0; - Standard_Integer aPointsOnSide = 100; - Standard_Real aStartPos[3] = {0.0, 0.0, 0.0}; - - Standard_Boolean hasColors = Standard_True; - Standard_Boolean hasAspect = Standard_False; - - // Parses arguments + // 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 == "-mode") + if (aFlag == "-randcolors" + || aFlag == "-randcolor") { - if (++anArgIter >= theArgNum) - { - std::cout << "Error: wrong syntax at " << anArg << std::endl; - return 1; - } - aModeSetPoints = Draw::Atoi (theArgs[anArgIter]); - if (aModeSetPoints < 0 || aModeSetPoints > 1) - { - std::cout << "Wrong value for argument " << aFlag << std::endl; - return 1; - } + toRandColors = Standard_True; } - else if (aFlag == "-nbpointsonside") + else if (aFlag == "-normals" + || aFlag == "-normal") { - if (++anArgIter >= theArgNum) - { - std::cout << "Error: wrong syntax at " << aFlag << std::endl; - return 1; - } - aPointsOnSide = Draw::Atoi (theArgs[anArgIter]); - if (aPointsOnSide <= 0) - { - std::cout << "Wrong value for argument " << aFlag << std::endl; - return 1; - } + hasNormals = Standard_True; } - else if (aFlag == "-markertype") + else if (aFlag == "-nonormals" + || aFlag == "-nonormal") { - if (++anArgIter >= theArgNum) - { - std::cout << "Error: wrong syntax at " << aFlag << std::endl; - return 1; - } - aMarkerType = Draw::Atoi (theArgs[anArgIter]); - hasAspect = Standard_True; - } - else if (aFlag == "-scale") - { - if (++anArgIter >= theArgNum) - { - std::cout << "Error: wrong syntax at " << aFlag << std::endl; - return 1; - } - aScale = Draw::Atof (theArgs[anArgIter]); - hasAspect = Standard_True; - } - else if (aFlag == "-color") - { - if (++anArgIter >= theArgNum) - { - std::cout << "Error: wrong syntax at " << aFlag << std::endl; - return 1; - } - aColorName = ViewerTest::GetColorFromName (theArgs[anArgIter]); - hasColors = Standard_False; - hasAspect = Standard_True; + hasNormals = Standard_False; } else { - std::cout << "Wrong argument: " << aFlag << std::endl; + std::cout << "Error: unknown argument '" << anArg << "'\n"; return 1; } } - Standard_Integer aNumberOfPoints = (Standard_Integer )Pow (aPointsOnSide, 3); - std::cout << "Number of points: " << aNumberOfPoints << std::endl; + // 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; + } - // Point cloud initialization + 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(); - if (aModeSetPoints == 0) - { - Handle(Graphic3d_ArrayOfPoints) anArrayPoints = new Graphic3d_ArrayOfPoints (aNumberOfPoints, - aNumberOfPoints != 1 && hasColors); - if (aNumberOfPoints == 1) - { - anArrayPoints->AddVertex (aStartPos[0], aStartPos[1], aStartPos[2]); - anArrayPoints->SetVertexColor (anArrayPoints->VertexNumber(), - Quantity_Color (Quantity_NOC_YELLOW)); - } - else - { - for (Standard_Real aStepX = 1; aStepX <= aPointsOnSide; aStepX++) - { - for (Standard_Real aStepY = 1; aStepY <= aPointsOnSide; aStepY++) - { - for (Standard_Real aStepZ = 1; aStepZ <= aPointsOnSide; aStepZ++) - { - anArrayPoints->AddVertex (aStartPos[0] + aStepX, - aStartPos[1] + aStepY, - aStartPos[2] + aStepZ); - anArrayPoints->SetVertexColor (anArrayPoints->VertexNumber(), - aStepX / aPointsOnSide, - aStepY / aPointsOnSide, - aStepZ / aPointsOnSide); - } - } - } - } - - if (anArrayPoints.IsNull() || !anArrayPoints->IsValid()) - { - std::cerr << "No points found." << std::endl; - return 1; - } - - // Set array of points in point cloud object - aPointCloud->SetPoints (anArrayPoints); - } - else if (aModeSetPoints == 1) - { - Handle(TColgp_HArray1OfPnt) aCoords = new TColgp_HArray1OfPnt (1, aNumberOfPoints); - for (Standard_Integer i = 1; i <= aNumberOfPoints; i++) - { - gp_Pnt aPoint (randomReal (0., 5000.), - randomReal (0., 5000.), - randomReal (0., 5000.)); - aCoords->SetValue (i, aPoint); - } - - Handle(Quantity_HArray1OfColor) aColors = new Quantity_HArray1OfColor (1, aNumberOfPoints); - if (hasColors) - { - for (Standard_Integer i = 1; i <= aNumberOfPoints; i++) - { - Quantity_Color aColor (360. * i / aNumberOfPoints, 1.0, 0.5, Quantity_TOC_HLS); - aColors->SetValue (i, aColor); - } - } - else - { - aColors.Nullify(); - } - // Set coordinates and colors - aPointCloud->SetPoints (aCoords, aColors); - } - - if (hasAspect) - { - // Set point aspect for attributes of interactive object - aPointCloud->Attributes()->SetPointAspect ( - new Prs3d_PointAspect (aMarkerType >= 0 ? (Aspect_TypeOfMarker )aMarkerType : Aspect_TOM_POINT, - aColorName, - aScale)); - } - + aPointCloud->SetPoints (anArrayPoints); VDisplayAISObject (aName, aPointCloud); - return 0; } @@ -5392,12 +5322,11 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) __FILE__, VFont, group); theCommands.Add ("vpointcloud", - "vpointcloud [name]" - "\n\t\t: [-mode ModeSetPoints]" - "\n\t\t: [-nbpointsonside NumberPointsOnSide]" - "\n\t\t: [-markertype TypeOfMarker]" - "\n\t\t: [-color ColorName]" - "\n\t\t: [-scale Scale]" - "\n\t\t: Create an interactive object for arbitary set of points.", - __FILE__, VPointCloud, group); + "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); }