0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / AIS / AIS_PointCloud.cxx
CommitLineData
d33222c1 1// Created on: 2014-08-13
2// Created by: Maxim GLIBIN
3// Copyright (c) 2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
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.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <AIS_PointCloud.hxx>
17
d33222c1 18#include <AIS_GraphicTool.hxx>
19#include <Graphic3d_AspectFillArea3d.hxx>
20#include <Graphic3d_AspectMarker3d.hxx>
21#include <Graphic3d_Group.hxx>
6262338c 22#include <Prs3d_Drawer.hxx>
d33222c1 23#include <Prs3d_PointAspect.hxx>
24#include <Prs3d_Presentation.hxx>
25#include <Prs3d_Root.hxx>
26#include <Prs3d_ShadingAspect.hxx>
d33222c1 27#include <PrsMgr_Presentations.hxx>
28#include <Select3D_SensitiveBox.hxx>
8b9a309b 29#include <Select3D_SensitivePrimitiveArray.hxx>
d33222c1 30#include <SelectMgr_EntityOwner.hxx>
31#include <SelectMgr_Selection.hxx>
5ad8c033 32#include <StdPrs_BndBox.hxx>
d33222c1 33
4a056d20 34IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloudOwner, SelectMgr_EntityOwner)
35IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject)
d33222c1 36
4a056d20 37//=======================================================================
38//function : AIS_PointCloudOwner
39//purpose :
40//=======================================================================
41AIS_PointCloudOwner::AIS_PointCloudOwner (const Handle(AIS_PointCloud)& theOrigin)
42: SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)& )theOrigin, 5),
43 myDetPoints (new TColStd_HPackedMapOfInteger()),
44 mySelPoints (new TColStd_HPackedMapOfInteger())
45{
46 //
47}
48
49//=======================================================================
50//function : ~AIS_PointCloudOwner
51//purpose :
52//=======================================================================
53AIS_PointCloudOwner::~AIS_PointCloudOwner()
54{
55 //
56}
57
58//=======================================================================
59//function : HilightWithColor
60//purpose :
61//=======================================================================
62Standard_Boolean AIS_PointCloudOwner::IsForcedHilight() const
63{
64 return true;
65}
66
67//=======================================================================
68//function : HilightWithColor
69//purpose :
70//=======================================================================
71void AIS_PointCloudOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
72 const Handle(Prs3d_Drawer)& theStyle,
73 const Standard_Integer )
74{
75 Handle(AIS_PointCloud) anObj = Handle(AIS_PointCloud)::DownCast (Selectable());
76 if (anObj.IsNull())
77 {
78 throw Standard_ProgramError ("Internal Error within AIS_PointCloud::PointsOwner!");
79 }
80
81 const Handle(TColStd_HPackedMapOfInteger)& aMap = thePrsMgr->IsImmediateModeOn()
82 ? myDetPoints
83 : mySelPoints;
84 Handle(Prs3d_Presentation) aPrs = thePrsMgr->IsImmediateModeOn()
85 ? anObj->GetHilightPresentation(thePrsMgr)
86 : anObj->GetSelectPresentation (thePrsMgr);
87 const Graphic3d_ZLayerId aZLayer = theStyle->ZLayer() != -1
88 ? theStyle->ZLayer()
89 : (thePrsMgr->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : anObj->ZLayer());
90 aMap->ChangeMap().Clear();
91 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
92 {
93 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
94 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
95 {
96 const Handle(SelectMgr_SensitiveEntity)& aSelEnt = aSelEntIter.Value();
97 if (aSelEnt->BaseSensitive()->OwnerId() == this)
98 {
99 if (Handle(Select3D_SensitivePrimitiveArray) aSensitive = Handle(Select3D_SensitivePrimitiveArray)::DownCast (aSelEnt->BaseSensitive()))
100 {
101 aMap->ChangeMap() = aSensitive->LastDetectedElementMap()->Map();
102 if (aSensitive->LastDetectedElement() != -1)
103 {
104 aMap->ChangeMap().Add (aSensitive->LastDetectedElement());
105 }
106 break;
107 }
108 }
109 }
110 }
111
112 aPrs->Clear();
113 if (aPrs->GetZLayer() != aZLayer)
114 {
115 aPrs->SetZLayer (aZLayer);
116 }
117 if (aMap->Map().IsEmpty())
118 {
119 return;
120 }
121
122 const Handle(Graphic3d_ArrayOfPoints) anAllPoints = anObj->GetPoints();
123 if (anAllPoints.IsNull())
124 {
125 return;
126 }
127
128 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (aMap->Map().Extent());
129 for (TColStd_PackedMapOfInteger::Iterator aPntIter (aMap->Map()); aPntIter.More(); aPntIter.Next())
130 {
131 const gp_Pnt aPnt = anAllPoints->Vertice (aPntIter.Key() + 1);
132 aPoints->AddVertex (aPnt);
133 }
134
135 Handle(Graphic3d_Group) aGroup = aPrs->NewGroup();
136 aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
137 aGroup->AddPrimitiveArray (aPoints);
138 if (thePrsMgr->IsImmediateModeOn())
139 {
140 thePrsMgr->AddToImmediateList (aPrs);
141 }
142 else
143 {
144 aPrs->Display();
145 }
146}
147
148//=======================================================================
149//function : Unhilight
150//purpose :
151//=======================================================================
152void AIS_PointCloudOwner::Unhilight (const Handle(PrsMgr_PresentationManager)& , const Standard_Integer )
153{
154 if (Handle(Prs3d_Presentation) aPrs = Selectable()->GetSelectPresentation (Handle(PrsMgr_PresentationManager3d)()))
155 {
156 aPrs->Erase();
157 }
158}
159
160//=======================================================================
161//function : Clear
162//purpose :
163//=======================================================================
164void AIS_PointCloudOwner::Clear (const Handle(PrsMgr_PresentationManager)& thePrsMgr, const Standard_Integer theMode)
165{
166 SelectMgr_EntityOwner::Clear (thePrsMgr, theMode);
167}
92efcf78 168
d33222c1 169//==================================================
170// Function: AIS_PointCloud
171// Purpose : Constructor
172//==================================================
173AIS_PointCloud::AIS_PointCloud()
174{
bf5f0ca2 175 myDrawer->SetupOwnShadingAspect();
176 myDrawer->ShadingAspect()->Aspect()->SetMarkerType (Aspect_TOM_POINT);
2831708b 177
d33222c1 178 SetDisplayMode (AIS_PointCloud::DM_Points);
179 SetHilightMode (AIS_PointCloud::DM_BndBox);
4a056d20 180
181 myDynHilightDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_CYAN1, 1.0));
d33222c1 182}
183
184//=======================================================================
185//function : GetPoints
186//purpose :
187//=======================================================================
188const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const
189{
190 return myPoints;
191}
192
193//=======================================================================
194//function : GetBoundingBox
195//purpose :
196//=======================================================================
197Bnd_Box AIS_PointCloud::GetBoundingBox() const
198{
199 return myBndBox;
200}
201
202//! Auxiliary method
203static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
204{
205 Bnd_Box aBndBox;
206 if (thePoints.IsNull())
207 {
208 return aBndBox;
209 }
210
211 const Standard_Integer aNbVertices = thePoints->VertexNumber();
212 for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
213 {
214 aBndBox.Add (thePoints->Vertice (aVertIter));
215 }
216 return aBndBox;
217}
218
219//=======================================================================
220//function : SetPoints
221//purpose :
222//=======================================================================
223void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
224{
225 myPoints = thePoints;
226 myBndBox = getBoundingBox (thePoints);
227}
228
229//=======================================================================
230//function : SetPoints
231//purpose :
232//=======================================================================
233void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
234 const Handle(Quantity_HArray1OfColor)& theColors,
235 const Handle(TColgp_HArray1OfDir)& theNormals)
236{
237 myPoints.Nullify();
238 myBndBox.SetVoid();
239 if (theCoords.IsNull())
240 {
241 return;
242 }
243
244 const Standard_Integer aNbPoints = theCoords->Length();
245 if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints)
246 || (!theColors.IsNull() && theColors->Length() != aNbPoints))
247 {
248 // invalid input
249 return;
250 }
251
252 const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints;
253 const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints;
254
255 const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0;
256 const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0;
257
258 myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals);
259 for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter)
260 {
261 myPoints->AddVertex (theCoords->Value (aPntIter));
262 if (hasColors)
263 {
264 myPoints->SetVertexColor (myPoints->VertexNumber(),
265 theColors->Value (aPntIter + aDiffColors));
266 }
267 if (hasNormals)
268 {
269 myPoints->SetVertexNormal (myPoints->VertexNumber(),
270 theNormals->Value (aPntIter + aDiffNormals));
271 }
272 }
273 myBndBox = getBoundingBox (myPoints);
274}
275
276//=======================================================================
277//function : SetColor
278//purpose :
279//=======================================================================
d33222c1 280void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
281{
282 AIS_InteractiveObject::SetColor(theColor);
283
d33222c1 284 myDrawer->ShadingAspect()->SetColor (theColor);
bf5f0ca2 285 SynchronizeAspects();
d33222c1 286}
287
288//=======================================================================
289//function : UnsetColor
290//purpose :
291//=======================================================================
292void AIS_PointCloud::UnsetColor()
293{
294 if (!HasColor())
295 {
296 return;
297 }
298
299 AIS_InteractiveObject::UnsetColor();
d33222c1 300 {
6262338c 301 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
302 Graphic3d_MaterialAspect aMat = aDefaultMat;
bf5f0ca2 303 Quantity_Color aColor = aDefaultMat.Color();
304 if (myDrawer->HasLink())
305 {
306 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
307 }
6262338c 308 if (HasMaterial() || myDrawer->HasLink())
309 {
310 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
311 }
d33222c1 312 if (HasMaterial())
313 {
d33222c1 314 aMat.SetColor (aColor);
315 }
316 if (IsTransparent())
317 {
318 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
4e1bc39a 319 aMat.SetTransparency (Standard_ShortReal(aTransp));
d33222c1 320 }
321 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
bf5f0ca2 322 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
d33222c1 323 }
d33222c1 324
bf5f0ca2 325 SynchronizeAspects();
d33222c1 326}
327
328//=======================================================================
329//function : SetMaterial
330//purpose :
331//=======================================================================
d33222c1 332void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
333{
d33222c1 334 hasOwnMaterial = Standard_True;
335
336 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
337 if (HasColor())
338 {
f838dac4 339 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
d33222c1 340 }
f838dac4 341 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
bf5f0ca2 342 SynchronizeAspects();
d33222c1 343}
344
345//=======================================================================
346//function : UnsetMaterial
347//purpose :
348//=======================================================================
349void AIS_PointCloud::UnsetMaterial()
350{
351 if (!HasMaterial())
352 {
353 return;
354 }
355
d33222c1 356 {
6262338c 357 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
358 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
359 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
360 aDefaultMat,
d33222c1 361 myCurrentFacingModel);
362 if (HasColor())
363 {
f838dac4 364 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
365 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
d33222c1 366 }
367 }
d33222c1 368 hasOwnMaterial = Standard_False;
bf5f0ca2 369 SynchronizeAspects();
d33222c1 370}
371
372//=======================================================================
373//function : Compute
374//purpose :
375//=======================================================================
376void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
377 const Handle(Prs3d_Presentation)& thePrs,
378 const Standard_Integer theMode)
379{
d33222c1 380 switch (theMode)
381 {
382 case AIS_PointCloud::DM_Points:
383 {
384 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
385 if (aPoints.IsNull())
386 {
387 return;
388 }
389
bf5f0ca2 390 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
2831708b 391 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
d33222c1 392 aGroup->AddPrimitiveArray (aPoints);
393 break;
394 }
395 case AIS_PointCloud::DM_BndBox:
396 {
397 Bnd_Box aBndBox = GetBoundingBox();
398 if (aBndBox.IsVoid())
399 {
400 return;
401 }
402
5ad8c033 403 StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer);
d33222c1 404 break;
405 }
406 }
407}
408
409//=======================================================================
410//function : ComputeSelection
411//purpose :
412//=======================================================================
413void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
8b9a309b 414 const Standard_Integer theMode)
d33222c1 415{
8b9a309b 416 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
417 switch (theMode)
418 {
419 case SM_Points:
4a056d20 420 case SM_SubsetOfPoints:
8b9a309b 421 {
422 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
423 if (!aPoints.IsNull()
424 && !aPoints->Attributes().IsNull())
425 {
4a056d20 426 if (theMode == SM_SubsetOfPoints)
427 {
428 anOwner = new AIS_PointCloudOwner (this);
429 }
430
a228288f 431 // split large point clouds into several groups
432 const Standard_Integer aNbGroups = aPoints->Attributes()->NbElements > 500000 ? 8 : 1;
8b9a309b 433 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
4a056d20 434 aSensitive->SetDetectElements (true);
435 aSensitive->SetDetectElementMap (theMode == SM_SubsetOfPoints);
8b9a309b 436 aSensitive->SetSensitivityFactor (8);
a228288f 437 aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location(), true, aNbGroups);
8b9a309b 438 aSensitive->BVH();
439 theSelection->Add (aSensitive);
440 return;
441 }
442 break;
443 }
444 case SM_BndBox:
445 {
446 break;
447 }
448 default:
449 {
450 return;
451 }
452 }
453
d33222c1 454 Bnd_Box aBndBox = GetBoundingBox();
455 if (aBndBox.IsVoid())
456 {
457 return;
458 }
d33222c1 459 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
460 theSelection->Add (aSensBox);
461}