mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
459 lines
15 KiB
C++
459 lines
15 KiB
C++
// 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 <AIS_PointCloud.hxx>
|
|
|
|
#include <AIS_GraphicTool.hxx>
|
|
#include <Graphic3d_AspectFillArea3d.hxx>
|
|
#include <Graphic3d_Group.hxx>
|
|
#include <Prs3d_Drawer.hxx>
|
|
#include <Prs3d_PointAspect.hxx>
|
|
#include <Prs3d_Presentation.hxx>
|
|
#include <Prs3d_ShadingAspect.hxx>
|
|
#include <Select3D_SensitiveBox.hxx>
|
|
#include <Select3D_SensitivePrimitiveArray.hxx>
|
|
#include <SelectMgr_EntityOwner.hxx>
|
|
#include <SelectMgr_Selection.hxx>
|
|
#include <Prs3d_BndBox.hxx>
|
|
|
|
IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloudOwner, SelectMgr_EntityOwner)
|
|
IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject)
|
|
|
|
//=======================================================================
|
|
//function : AIS_PointCloudOwner
|
|
//purpose :
|
|
//=======================================================================
|
|
AIS_PointCloudOwner::AIS_PointCloudOwner (const Handle(AIS_PointCloud)& theOrigin)
|
|
: SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)& )theOrigin, 5),
|
|
myDetPoints (new TColStd_HPackedMapOfInteger()),
|
|
mySelPoints (new TColStd_HPackedMapOfInteger())
|
|
{
|
|
//
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ~AIS_PointCloudOwner
|
|
//purpose :
|
|
//=======================================================================
|
|
AIS_PointCloudOwner::~AIS_PointCloudOwner()
|
|
{
|
|
//
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : HilightWithColor
|
|
//purpose :
|
|
//=======================================================================
|
|
Standard_Boolean AIS_PointCloudOwner::IsForcedHilight() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : HilightWithColor
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloudOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
|
|
const Handle(Prs3d_Drawer)& theStyle,
|
|
const Standard_Integer )
|
|
{
|
|
Handle(AIS_PointCloud) anObj = Handle(AIS_PointCloud)::DownCast (Selectable());
|
|
if (anObj.IsNull())
|
|
{
|
|
throw Standard_ProgramError ("Internal Error within AIS_PointCloud::PointsOwner!");
|
|
}
|
|
|
|
const Handle(TColStd_HPackedMapOfInteger)& aMap = thePrsMgr->IsImmediateModeOn()
|
|
? myDetPoints
|
|
: mySelPoints;
|
|
Handle(Prs3d_Presentation) aPrs = thePrsMgr->IsImmediateModeOn()
|
|
? anObj->GetHilightPresentation(thePrsMgr)
|
|
: anObj->GetSelectPresentation (thePrsMgr);
|
|
const Graphic3d_ZLayerId aZLayer = theStyle->ZLayer() != -1
|
|
? theStyle->ZLayer()
|
|
: (thePrsMgr->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : anObj->ZLayer());
|
|
aMap->ChangeMap().Clear();
|
|
for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
|
|
{
|
|
const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
|
|
for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
|
|
{
|
|
const Handle(SelectMgr_SensitiveEntity)& aSelEnt = aSelEntIter.Value();
|
|
if (aSelEnt->BaseSensitive()->OwnerId() == this)
|
|
{
|
|
if (Handle(Select3D_SensitivePrimitiveArray) aSensitive = Handle(Select3D_SensitivePrimitiveArray)::DownCast (aSelEnt->BaseSensitive()))
|
|
{
|
|
aMap->ChangeMap() = aSensitive->LastDetectedElementMap()->Map();
|
|
if (aSensitive->LastDetectedElement() != -1)
|
|
{
|
|
aMap->ChangeMap().Add (aSensitive->LastDetectedElement());
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
aPrs->Clear();
|
|
if (aPrs->GetZLayer() != aZLayer)
|
|
{
|
|
aPrs->SetZLayer (aZLayer);
|
|
}
|
|
if (aMap->Map().IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
const Handle(Graphic3d_ArrayOfPoints) anAllPoints = anObj->GetPoints();
|
|
if (anAllPoints.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (aMap->Map().Extent());
|
|
for (TColStd_PackedMapOfInteger::Iterator aPntIter (aMap->Map()); aPntIter.More(); aPntIter.Next())
|
|
{
|
|
const gp_Pnt aPnt = anAllPoints->Vertice (aPntIter.Key() + 1);
|
|
aPoints->AddVertex (aPnt);
|
|
}
|
|
|
|
Handle(Graphic3d_Group) aGroup = aPrs->NewGroup();
|
|
aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
|
|
aGroup->AddPrimitiveArray (aPoints);
|
|
if (thePrsMgr->IsImmediateModeOn())
|
|
{
|
|
thePrsMgr->AddToImmediateList (aPrs);
|
|
}
|
|
else
|
|
{
|
|
aPrs->Display();
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Unhilight
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloudOwner::Unhilight (const Handle(PrsMgr_PresentationManager)& , const Standard_Integer )
|
|
{
|
|
if (Handle(Prs3d_Presentation) aPrs = Selectable()->GetSelectPresentation (Handle(PrsMgr_PresentationManager)()))
|
|
{
|
|
aPrs->Erase();
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Clear
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloudOwner::Clear (const Handle(PrsMgr_PresentationManager)& thePrsMgr, const Standard_Integer theMode)
|
|
{
|
|
SelectMgr_EntityOwner::Clear (thePrsMgr, theMode);
|
|
}
|
|
|
|
//==================================================
|
|
// Function: AIS_PointCloud
|
|
// Purpose : Constructor
|
|
//==================================================
|
|
AIS_PointCloud::AIS_PointCloud()
|
|
{
|
|
myDrawer->SetupOwnShadingAspect();
|
|
myDrawer->ShadingAspect()->Aspect()->SetMarkerType (Aspect_TOM_POINT);
|
|
|
|
SetDisplayMode (AIS_PointCloud::DM_Points);
|
|
SetHilightMode (AIS_PointCloud::DM_BndBox);
|
|
|
|
myDynHilightDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_CYAN1, 1.0));
|
|
}
|
|
|
|
//=======================================================================
|
|
//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_Color& theColor)
|
|
{
|
|
AIS_InteractiveObject::SetColor(theColor);
|
|
|
|
myDrawer->ShadingAspect()->SetColor (theColor);
|
|
SynchronizeAspects();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : UnsetColor
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloud::UnsetColor()
|
|
{
|
|
if (!HasColor())
|
|
{
|
|
return;
|
|
}
|
|
|
|
AIS_InteractiveObject::UnsetColor();
|
|
{
|
|
Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NameOfMaterial_Brass);
|
|
Graphic3d_MaterialAspect aMat = aDefaultMat;
|
|
Quantity_Color aColor = aDefaultMat.Color();
|
|
if (myDrawer->HasLink())
|
|
{
|
|
aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
|
|
}
|
|
if (HasMaterial() || myDrawer->HasLink())
|
|
{
|
|
aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
|
|
}
|
|
if (HasMaterial())
|
|
{
|
|
aMat.SetColor (aColor);
|
|
}
|
|
if (IsTransparent())
|
|
{
|
|
Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
|
|
aMat.SetTransparency (Standard_ShortReal(aTransp));
|
|
}
|
|
myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
|
|
myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
|
|
}
|
|
|
|
SynchronizeAspects();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetMaterial
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
|
|
{
|
|
hasOwnMaterial = Standard_True;
|
|
|
|
myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
|
|
if (HasColor())
|
|
{
|
|
myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
|
|
}
|
|
myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
|
|
SynchronizeAspects();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : UnsetMaterial
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloud::UnsetMaterial()
|
|
{
|
|
if (!HasMaterial())
|
|
{
|
|
return;
|
|
}
|
|
|
|
{
|
|
Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NameOfMaterial_Brass);
|
|
myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
|
|
myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
|
|
aDefaultMat,
|
|
myCurrentFacingModel);
|
|
if (HasColor())
|
|
{
|
|
myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
|
|
myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
|
|
}
|
|
}
|
|
hasOwnMaterial = Standard_False;
|
|
SynchronizeAspects();
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Compute
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager)& ,
|
|
const Handle(Prs3d_Presentation)& thePrs,
|
|
const Standard_Integer theMode)
|
|
{
|
|
switch (theMode)
|
|
{
|
|
case AIS_PointCloud::DM_Points:
|
|
{
|
|
const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
|
|
if (aPoints.IsNull())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
|
|
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
|
|
aGroup->AddPrimitiveArray (aPoints);
|
|
break;
|
|
}
|
|
case AIS_PointCloud::DM_BndBox:
|
|
{
|
|
Bnd_Box aBndBox = GetBoundingBox();
|
|
if (aBndBox.IsVoid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
Prs3d_BndBox::Add (thePrs, aBndBox, myDrawer);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : ComputeSelection
|
|
//purpose :
|
|
//=======================================================================
|
|
void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
|
|
const Standard_Integer theMode)
|
|
{
|
|
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
|
|
switch (theMode)
|
|
{
|
|
case SM_Points:
|
|
case SM_SubsetOfPoints:
|
|
{
|
|
const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
|
|
if (!aPoints.IsNull()
|
|
&& !aPoints->Attributes().IsNull())
|
|
{
|
|
if (theMode == SM_SubsetOfPoints)
|
|
{
|
|
anOwner = new AIS_PointCloudOwner (this);
|
|
}
|
|
|
|
// split large point clouds into several groups
|
|
const Standard_Integer aNbGroups = aPoints->Attributes()->NbElements > 500000 ? 8 : 1;
|
|
Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
|
|
aSensitive->SetDetectElements (true);
|
|
aSensitive->SetDetectElementMap (theMode == SM_SubsetOfPoints);
|
|
aSensitive->SetSensitivityFactor (8);
|
|
aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location(), true, aNbGroups);
|
|
aSensitive->BVH();
|
|
theSelection->Add (aSensitive);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case SM_BndBox:
|
|
{
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
Bnd_Box aBndBox = GetBoundingBox();
|
|
if (aBndBox.IsVoid())
|
|
{
|
|
return;
|
|
}
|
|
Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
|
|
theSelection->Add (aSensBox);
|
|
}
|