0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / AIS / AIS_PointCloud.cxx
... / ...
CommitLineData
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
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_Presentations.hxx>
28#include <Select3D_SensitiveBox.hxx>
29#include <Select3D_SensitivePrimitiveArray.hxx>
30#include <SelectMgr_EntityOwner.hxx>
31#include <SelectMgr_Selection.hxx>
32#include <StdPrs_BndBox.hxx>
33
34IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloudOwner, SelectMgr_EntityOwner)
35IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject)
36
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}
168
169//==================================================
170// Function: AIS_PointCloud
171// Purpose : Constructor
172//==================================================
173AIS_PointCloud::AIS_PointCloud()
174{
175 myDrawer->SetupOwnShadingAspect();
176 myDrawer->ShadingAspect()->Aspect()->SetMarkerType (Aspect_TOM_POINT);
177
178 SetDisplayMode (AIS_PointCloud::DM_Points);
179 SetHilightMode (AIS_PointCloud::DM_BndBox);
180
181 myDynHilightDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_CYAN1, 1.0));
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//=======================================================================
280void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
281{
282 AIS_InteractiveObject::SetColor(theColor);
283
284 myDrawer->ShadingAspect()->SetColor (theColor);
285 SynchronizeAspects();
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();
300 {
301 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
302 Graphic3d_MaterialAspect aMat = aDefaultMat;
303 Quantity_Color aColor = aDefaultMat.Color();
304 if (myDrawer->HasLink())
305 {
306 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
307 }
308 if (HasMaterial() || myDrawer->HasLink())
309 {
310 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
311 }
312 if (HasMaterial())
313 {
314 aMat.SetColor (aColor);
315 }
316 if (IsTransparent())
317 {
318 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
319 aMat.SetTransparency (Standard_ShortReal(aTransp));
320 }
321 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
322 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
323 }
324
325 SynchronizeAspects();
326}
327
328//=======================================================================
329//function : SetMaterial
330//purpose :
331//=======================================================================
332void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
333{
334 hasOwnMaterial = Standard_True;
335
336 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
337 if (HasColor())
338 {
339 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
340 }
341 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
342 SynchronizeAspects();
343}
344
345//=======================================================================
346//function : UnsetMaterial
347//purpose :
348//=======================================================================
349void AIS_PointCloud::UnsetMaterial()
350{
351 if (!HasMaterial())
352 {
353 return;
354 }
355
356 {
357 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
358 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
359 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
360 aDefaultMat,
361 myCurrentFacingModel);
362 if (HasColor())
363 {
364 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
365 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
366 }
367 }
368 hasOwnMaterial = Standard_False;
369 SynchronizeAspects();
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{
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
390 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
391 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
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
403 StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer);
404 break;
405 }
406 }
407}
408
409//=======================================================================
410//function : ComputeSelection
411//purpose :
412//=======================================================================
413void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
414 const Standard_Integer theMode)
415{
416 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
417 switch (theMode)
418 {
419 case SM_Points:
420 case SM_SubsetOfPoints:
421 {
422 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
423 if (!aPoints.IsNull()
424 && !aPoints->Attributes().IsNull())
425 {
426 if (theMode == SM_SubsetOfPoints)
427 {
428 anOwner = new AIS_PointCloudOwner (this);
429 }
430
431 // split large point clouds into several groups
432 const Standard_Integer aNbGroups = aPoints->Attributes()->NbElements > 500000 ? 8 : 1;
433 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
434 aSensitive->SetDetectElements (true);
435 aSensitive->SetDetectElementMap (theMode == SM_SubsetOfPoints);
436 aSensitive->SetSensitivityFactor (8);
437 aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location(), true, aNbGroups);
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
454 Bnd_Box aBndBox = GetBoundingBox();
455 if (aBndBox.IsVoid())
456 {
457 return;
458 }
459 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
460 theSelection->Add (aSensBox);
461}