0026885: Visualization - drop redundant aspects from structure level
[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>
27#include <PrsMgr_ModedPresentation.hxx>
28#include <PrsMgr_Presentations.hxx>
29#include <Select3D_SensitiveBox.hxx>
8b9a309b 30#include <Select3D_SensitivePrimitiveArray.hxx>
d33222c1 31#include <SelectMgr_EntityOwner.hxx>
32#include <SelectMgr_Selection.hxx>
5ad8c033 33#include <StdPrs_BndBox.hxx>
d33222c1 34
d33222c1 35
92efcf78 36IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud,AIS_InteractiveObject)
37
d33222c1 38//==================================================
39// Function: AIS_PointCloud
40// Purpose : Constructor
41//==================================================
42AIS_PointCloud::AIS_PointCloud()
43{
2831708b 44 // override default point style to Aspect_TOM_POINT
45 myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0));
46
d33222c1 47 SetDisplayMode (AIS_PointCloud::DM_Points);
48 SetHilightMode (AIS_PointCloud::DM_BndBox);
49}
50
51//=======================================================================
52//function : GetPoints
53//purpose :
54//=======================================================================
55const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const
56{
57 return myPoints;
58}
59
60//=======================================================================
61//function : GetBoundingBox
62//purpose :
63//=======================================================================
64Bnd_Box AIS_PointCloud::GetBoundingBox() const
65{
66 return myBndBox;
67}
68
69//! Auxiliary method
70static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
71{
72 Bnd_Box aBndBox;
73 if (thePoints.IsNull())
74 {
75 return aBndBox;
76 }
77
78 const Standard_Integer aNbVertices = thePoints->VertexNumber();
79 for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
80 {
81 aBndBox.Add (thePoints->Vertice (aVertIter));
82 }
83 return aBndBox;
84}
85
86//=======================================================================
87//function : SetPoints
88//purpose :
89//=======================================================================
90void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
91{
92 myPoints = thePoints;
93 myBndBox = getBoundingBox (thePoints);
94}
95
96//=======================================================================
97//function : SetPoints
98//purpose :
99//=======================================================================
100void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
101 const Handle(Quantity_HArray1OfColor)& theColors,
102 const Handle(TColgp_HArray1OfDir)& theNormals)
103{
104 myPoints.Nullify();
105 myBndBox.SetVoid();
106 if (theCoords.IsNull())
107 {
108 return;
109 }
110
111 const Standard_Integer aNbPoints = theCoords->Length();
112 if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints)
113 || (!theColors.IsNull() && theColors->Length() != aNbPoints))
114 {
115 // invalid input
116 return;
117 }
118
119 const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints;
120 const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints;
121
122 const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0;
123 const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0;
124
125 myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals);
126 for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter)
127 {
128 myPoints->AddVertex (theCoords->Value (aPntIter));
129 if (hasColors)
130 {
131 myPoints->SetVertexColor (myPoints->VertexNumber(),
132 theColors->Value (aPntIter + aDiffColors));
133 }
134 if (hasNormals)
135 {
136 myPoints->SetVertexNormal (myPoints->VertexNumber(),
137 theNormals->Value (aPntIter + aDiffNormals));
138 }
139 }
140 myBndBox = getBoundingBox (myPoints);
141}
142
143//=======================================================================
144//function : SetColor
145//purpose :
146//=======================================================================
147void AIS_PointCloud::SetColor (const Quantity_NameOfColor theColor)
148{
149 SetColor (Quantity_Color (theColor));
150}
151
152//=======================================================================
153//function : SetColor
154//purpose :
155//=======================================================================
156void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
157{
158 AIS_InteractiveObject::SetColor(theColor);
159
6262338c 160 if (!myDrawer->HasOwnPointAspect())
d33222c1 161 {
162 myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, theColor, 1.0));
6262338c 163 if (myDrawer->HasLink())
164 {
165 *myDrawer->PointAspect()->Aspect() = *myDrawer->Link()->PointAspect()->Aspect();
166 }
d33222c1 167 }
6262338c 168 if (!myDrawer->HasOwnShadingAspect())
d33222c1 169 {
170 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6262338c 171 if (myDrawer->HasLink())
172 {
173 *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
174 }
d33222c1 175 }
176
177 // Override color
178 myDrawer->ShadingAspect()->SetColor (theColor);
179 myDrawer->PointAspect() ->SetColor (theColor);
180
181 const PrsMgr_Presentations& aPrsList = Presentations();
182 Handle(Graphic3d_AspectMarker3d) aPointAspect = myDrawer->PointAspect()->Aspect();
183 Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
184 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
185 {
186 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
187 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
188 {
189 continue;
190 }
191
192 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 193 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
194 {
195 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
196 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
197 {
198 aGroup->SetGroupPrimitivesAspect (aPointAspect);
199 }
200 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
201 {
202 aGroup->SetGroupPrimitivesAspect (anAreaAspect);
203 }
204 }
205 }
206}
207
208//=======================================================================
209//function : UnsetColor
210//purpose :
211//=======================================================================
212void AIS_PointCloud::UnsetColor()
213{
214 if (!HasColor())
215 {
216 return;
217 }
218
219 AIS_InteractiveObject::UnsetColor();
220
221 if (!HasWidth())
222 {
223 myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
224 }
225 else
226 {
6262338c 227 Quantity_Color aColor = Quantity_NOC_YELLOW;
d33222c1 228 Aspect_TypeOfMarker aType = Aspect_TOM_POINT;
229 Standard_Real aScale = 1.0;
6262338c 230 if (myDrawer->HasLink())
231 {
232 myDrawer->Link()->PointAspect()->Aspect()->Values (aColor, aType, aScale);
233 }
d33222c1 234 myDrawer->PointAspect()->SetColor (aColor);
235 }
236
237 if (HasMaterial()
238 || IsTransparent())
239 {
6262338c 240 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
241 Graphic3d_MaterialAspect aMat = aDefaultMat;
242 if (HasMaterial() || myDrawer->HasLink())
243 {
244 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
245 }
d33222c1 246 if (HasMaterial())
247 {
6262338c 248 Quantity_Color aColor = aDefaultMat.AmbientColor();
249 if (myDrawer->HasLink())
250 {
251 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
252 }
d33222c1 253 aMat.SetColor (aColor);
254 }
255 if (IsTransparent())
256 {
257 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
258 aMat.SetTransparency (aTransp);
259 }
260 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
261 }
262 else
263 {
264 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
265 }
266 myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
267
268 // modify shading presentation without re-computation
269 const PrsMgr_Presentations& aPrsList = Presentations();
270 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
271 Handle(Graphic3d_AspectMarker3d) aMarkerAsp = myDrawer->Link()->PointAspect()->Aspect();
272 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
273 {
274 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
275 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
276 {
277 continue;
278 }
279
280 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 281 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
282 {
283 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
284
285 // Check if aspect of given type is set for the group,
286 // because setting aspect for group with no already set aspect
287 // can lead to loss of presentation data
288 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
289 {
290 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
291 }
292 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
293 {
294 aGroup->SetGroupPrimitivesAspect (aMarkerAsp);
295 }
296 }
297 }
298}
299
300//=======================================================================
301//function : SetMaterial
302//purpose :
303//=======================================================================
304void AIS_PointCloud::SetMaterial (const Graphic3d_NameOfMaterial theMatName)
305{
306 SetMaterial (Graphic3d_MaterialAspect (theMatName));
307}
308
309//=======================================================================
310//function : SetMaterial
311//purpose :
312//=======================================================================
313void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
314{
6262338c 315 if (!myDrawer->HasOwnShadingAspect())
d33222c1 316 {
317 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6262338c 318 if (myDrawer->HasLink())
319 {
320 *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
321 }
d33222c1 322 }
323 hasOwnMaterial = Standard_True;
324
325 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
326 if (HasColor())
327 {
328 myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
329 }
330 myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
331
332 // modify shading presentation without re-computation
333 const PrsMgr_Presentations& aPrsList = Presentations();
334 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
335 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
336 {
337 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
338 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
339 {
340 continue;
341 }
342
343 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 344 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
345 {
346 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
347 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
348 {
349 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
350 }
351 }
352 }
353}
354
355//=======================================================================
356//function : UnsetMaterial
357//purpose :
358//=======================================================================
359void AIS_PointCloud::UnsetMaterial()
360{
361 if (!HasMaterial())
362 {
363 return;
364 }
365
366 if (HasColor()
367 || IsTransparent())
368 {
6262338c 369 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
370 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
371 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
372 aDefaultMat,
d33222c1 373 myCurrentFacingModel);
374 if (HasColor())
375 {
376 myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
377 myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
378 }
379 }
380 else
381 {
382 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
383 }
384 hasOwnMaterial = Standard_False;
385
386 // modify shading presentation without re-computation
387 const PrsMgr_Presentations& aPrsList = Presentations();
388 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
389 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
390 {
391 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
392 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
393 {
394 continue;
395 }
396
397 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 398 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
399 {
400 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
401 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
402 {
403 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
404 }
405 }
406 }
407}
408
409//=======================================================================
410//function : Compute
411//purpose :
412//=======================================================================
413void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
414 const Handle(Prs3d_Presentation)& thePrs,
415 const Standard_Integer theMode)
416{
417 thePrs->Clear();
418 switch (theMode)
419 {
420 case AIS_PointCloud::DM_Points:
421 {
422 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
423 if (aPoints.IsNull())
424 {
425 return;
426 }
427
d33222c1 428 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
2831708b 429 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
430 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
d33222c1 431 aGroup->AddPrimitiveArray (aPoints);
432 break;
433 }
434 case AIS_PointCloud::DM_BndBox:
435 {
436 Bnd_Box aBndBox = GetBoundingBox();
437 if (aBndBox.IsVoid())
438 {
439 return;
440 }
441
5ad8c033 442 StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer);
d33222c1 443 break;
444 }
445 }
446}
447
448//=======================================================================
449//function : ComputeSelection
450//purpose :
451//=======================================================================
452void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
8b9a309b 453 const Standard_Integer theMode)
d33222c1 454{
8b9a309b 455 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
456 switch (theMode)
457 {
458 case SM_Points:
459 {
460 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
461 if (!aPoints.IsNull()
462 && !aPoints->Attributes().IsNull())
463 {
464 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
465 aSensitive->SetSensitivityFactor (8);
466 aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location());
467 aSensitive->BVH();
468 theSelection->Add (aSensitive);
469 return;
470 }
471 break;
472 }
473 case SM_BndBox:
474 {
475 break;
476 }
477 default:
478 {
479 return;
480 }
481 }
482
d33222c1 483 Bnd_Box aBndBox = GetBoundingBox();
484 if (aBndBox.IsVoid())
485 {
486 return;
487 }
d33222c1 488 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
489 theSelection->Add (aSensBox);
490}