1 // Created on: 2014-08-13
2 // Created by: Maxim GLIBIN
3 // Copyright (c) 2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <AIS_PointCloud.hxx>
18 #include <AIS_GraphicTool.hxx>
19 #include <Graphic3d_AspectFillArea3d.hxx>
20 #include <Graphic3d_AspectMarker3d.hxx>
21 #include <Graphic3d_Group.hxx>
22 #include <Prs3d_Drawer.hxx>
23 #include <Prs3d_PointAspect.hxx>
24 #include <Prs3d_Presentation.hxx>
25 #include <Prs3d_Root.hxx>
26 #include <Prs3d_ShadingAspect.hxx>
27 #include <PrsMgr_ModedPresentation.hxx>
28 #include <PrsMgr_Presentations.hxx>
29 #include <Select3D_SensitiveBox.hxx>
30 #include <Select3D_SensitivePrimitiveArray.hxx>
31 #include <SelectMgr_EntityOwner.hxx>
32 #include <SelectMgr_Selection.hxx>
33 #include <StdPrs_BndBox.hxx>
35 IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloudOwner, SelectMgr_EntityOwner)
36 IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject)
38 //=======================================================================
39 //function : AIS_PointCloudOwner
41 //=======================================================================
42 AIS_PointCloudOwner::AIS_PointCloudOwner (const Handle(AIS_PointCloud)& theOrigin)
43 : SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)& )theOrigin, 5),
44 myDetPoints (new TColStd_HPackedMapOfInteger()),
45 mySelPoints (new TColStd_HPackedMapOfInteger())
50 //=======================================================================
51 //function : ~AIS_PointCloudOwner
53 //=======================================================================
54 AIS_PointCloudOwner::~AIS_PointCloudOwner()
59 //=======================================================================
60 //function : HilightWithColor
62 //=======================================================================
63 Standard_Boolean AIS_PointCloudOwner::IsForcedHilight() const
68 //=======================================================================
69 //function : HilightWithColor
71 //=======================================================================
72 void AIS_PointCloudOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
73 const Handle(Prs3d_Drawer)& theStyle,
74 const Standard_Integer )
76 Handle(AIS_PointCloud) anObj = Handle(AIS_PointCloud)::DownCast (Selectable());
79 throw Standard_ProgramError ("Internal Error within AIS_PointCloud::PointsOwner!");
82 const Handle(TColStd_HPackedMapOfInteger)& aMap = thePrsMgr->IsImmediateModeOn()
85 Handle(Prs3d_Presentation) aPrs = thePrsMgr->IsImmediateModeOn()
86 ? anObj->GetHilightPresentation(thePrsMgr)
87 : anObj->GetSelectPresentation (thePrsMgr);
88 const Graphic3d_ZLayerId aZLayer = theStyle->ZLayer() != -1
90 : (thePrsMgr->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : anObj->ZLayer());
91 aMap->ChangeMap().Clear();
92 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
94 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
95 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
97 const Handle(SelectMgr_SensitiveEntity)& aSelEnt = aSelEntIter.Value();
98 if (aSelEnt->BaseSensitive()->OwnerId() == this)
100 if (Handle(Select3D_SensitivePrimitiveArray) aSensitive = Handle(Select3D_SensitivePrimitiveArray)::DownCast (aSelEnt->BaseSensitive()))
102 aMap->ChangeMap() = aSensitive->LastDetectedElementMap()->Map();
103 if (aSensitive->LastDetectedElement() != -1)
105 aMap->ChangeMap().Add (aSensitive->LastDetectedElement());
114 if (aPrs->GetZLayer() != aZLayer)
116 aPrs->SetZLayer (aZLayer);
118 if (aMap->Map().IsEmpty())
123 const Handle(Graphic3d_ArrayOfPoints) anAllPoints = anObj->GetPoints();
124 if (anAllPoints.IsNull())
129 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (aMap->Map().Extent());
130 for (TColStd_PackedMapOfInteger::Iterator aPntIter (aMap->Map()); aPntIter.More(); aPntIter.Next())
132 const gp_Pnt aPnt = anAllPoints->Vertice (aPntIter.Key() + 1);
133 aPoints->AddVertex (aPnt);
136 Handle(Graphic3d_Group) aGroup = aPrs->NewGroup();
137 aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
138 aGroup->AddPrimitiveArray (aPoints);
139 if (thePrsMgr->IsImmediateModeOn())
141 thePrsMgr->AddToImmediateList (aPrs);
149 //=======================================================================
150 //function : Unhilight
152 //=======================================================================
153 void AIS_PointCloudOwner::Unhilight (const Handle(PrsMgr_PresentationManager)& , const Standard_Integer )
155 if (Handle(Prs3d_Presentation) aPrs = Selectable()->GetSelectPresentation (Handle(PrsMgr_PresentationManager3d)()))
161 //=======================================================================
164 //=======================================================================
165 void AIS_PointCloudOwner::Clear (const Handle(PrsMgr_PresentationManager)& thePrsMgr, const Standard_Integer theMode)
167 SelectMgr_EntityOwner::Clear (thePrsMgr, theMode);
170 //==================================================
171 // Function: AIS_PointCloud
172 // Purpose : Constructor
173 //==================================================
174 AIS_PointCloud::AIS_PointCloud()
176 myDrawer->SetupOwnShadingAspect();
177 myDrawer->ShadingAspect()->Aspect()->SetMarkerType (Aspect_TOM_POINT);
179 SetDisplayMode (AIS_PointCloud::DM_Points);
180 SetHilightMode (AIS_PointCloud::DM_BndBox);
182 myDynHilightDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_CYAN1, 1.0));
185 //=======================================================================
186 //function : GetPoints
188 //=======================================================================
189 const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const
194 //=======================================================================
195 //function : GetBoundingBox
197 //=======================================================================
198 Bnd_Box AIS_PointCloud::GetBoundingBox() const
204 static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
207 if (thePoints.IsNull())
212 const Standard_Integer aNbVertices = thePoints->VertexNumber();
213 for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
215 aBndBox.Add (thePoints->Vertice (aVertIter));
220 //=======================================================================
221 //function : SetPoints
223 //=======================================================================
224 void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
226 myPoints = thePoints;
227 myBndBox = getBoundingBox (thePoints);
230 //=======================================================================
231 //function : SetPoints
233 //=======================================================================
234 void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
235 const Handle(Quantity_HArray1OfColor)& theColors,
236 const Handle(TColgp_HArray1OfDir)& theNormals)
240 if (theCoords.IsNull())
245 const Standard_Integer aNbPoints = theCoords->Length();
246 if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints)
247 || (!theColors.IsNull() && theColors->Length() != aNbPoints))
253 const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints;
254 const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints;
256 const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0;
257 const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0;
259 myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals);
260 for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter)
262 myPoints->AddVertex (theCoords->Value (aPntIter));
265 myPoints->SetVertexColor (myPoints->VertexNumber(),
266 theColors->Value (aPntIter + aDiffColors));
270 myPoints->SetVertexNormal (myPoints->VertexNumber(),
271 theNormals->Value (aPntIter + aDiffNormals));
274 myBndBox = getBoundingBox (myPoints);
277 //=======================================================================
278 //function : SetColor
280 //=======================================================================
281 void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
283 AIS_InteractiveObject::SetColor(theColor);
285 myDrawer->ShadingAspect()->SetColor (theColor);
286 SynchronizeAspects();
289 //=======================================================================
290 //function : UnsetColor
292 //=======================================================================
293 void AIS_PointCloud::UnsetColor()
300 AIS_InteractiveObject::UnsetColor();
302 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
303 Graphic3d_MaterialAspect aMat = aDefaultMat;
304 Quantity_Color aColor = aDefaultMat.Color();
305 if (myDrawer->HasLink())
307 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
309 if (HasMaterial() || myDrawer->HasLink())
311 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
315 aMat.SetColor (aColor);
319 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
320 aMat.SetTransparency (Standard_ShortReal(aTransp));
322 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
323 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
326 SynchronizeAspects();
329 //=======================================================================
330 //function : SetMaterial
332 //=======================================================================
333 void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
335 hasOwnMaterial = Standard_True;
337 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
340 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
342 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
343 SynchronizeAspects();
346 //=======================================================================
347 //function : UnsetMaterial
349 //=======================================================================
350 void AIS_PointCloud::UnsetMaterial()
358 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
359 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
360 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
362 myCurrentFacingModel);
365 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
366 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
369 hasOwnMaterial = Standard_False;
370 SynchronizeAspects();
373 //=======================================================================
376 //=======================================================================
377 void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
378 const Handle(Prs3d_Presentation)& thePrs,
379 const Standard_Integer theMode)
383 case AIS_PointCloud::DM_Points:
385 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
386 if (aPoints.IsNull())
391 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
392 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
393 aGroup->AddPrimitiveArray (aPoints);
396 case AIS_PointCloud::DM_BndBox:
398 Bnd_Box aBndBox = GetBoundingBox();
399 if (aBndBox.IsVoid())
404 StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer);
410 //=======================================================================
411 //function : ComputeSelection
413 //=======================================================================
414 void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
415 const Standard_Integer theMode)
417 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
421 case SM_SubsetOfPoints:
423 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
424 if (!aPoints.IsNull()
425 && !aPoints->Attributes().IsNull())
427 if (theMode == SM_SubsetOfPoints)
429 anOwner = new AIS_PointCloudOwner (this);
432 // split large point clouds into several groups
433 const Standard_Integer aNbGroups = aPoints->Attributes()->NbElements > 500000 ? 8 : 1;
434 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
435 aSensitive->SetDetectElements (true);
436 aSensitive->SetDetectElementMap (theMode == SM_SubsetOfPoints);
437 aSensitive->SetSensitivityFactor (8);
438 aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location(), true, aNbGroups);
440 theSelection->Add (aSensitive);
455 Bnd_Box aBndBox = GetBoundingBox();
456 if (aBndBox.IsVoid())
460 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
461 theSelection->Add (aSensBox);