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