0027670: Visualization - avoid duplication of structures defining primitive array...
[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 {
b6472664 227 myDrawer->PointAspect()->SetColor (myDrawer->HasLink()
228 ? myDrawer->Link()->PointAspect()->Aspect()->Color()
229 : Quantity_Color (Quantity_NOC_YELLOW));
d33222c1 230 }
231
232 if (HasMaterial()
233 || IsTransparent())
234 {
6262338c 235 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
236 Graphic3d_MaterialAspect aMat = aDefaultMat;
237 if (HasMaterial() || myDrawer->HasLink())
238 {
239 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
240 }
d33222c1 241 if (HasMaterial())
242 {
6262338c 243 Quantity_Color aColor = aDefaultMat.AmbientColor();
244 if (myDrawer->HasLink())
245 {
246 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
247 }
d33222c1 248 aMat.SetColor (aColor);
249 }
250 if (IsTransparent())
251 {
252 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
253 aMat.SetTransparency (aTransp);
254 }
255 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
256 }
257 else
258 {
259 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
260 }
261 myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
262
263 // modify shading presentation without re-computation
264 const PrsMgr_Presentations& aPrsList = Presentations();
265 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
266 Handle(Graphic3d_AspectMarker3d) aMarkerAsp = myDrawer->Link()->PointAspect()->Aspect();
267 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
268 {
269 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
270 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
271 {
272 continue;
273 }
274
275 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 276 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
277 {
278 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
279
280 // Check if aspect of given type is set for the group,
281 // because setting aspect for group with no already set aspect
282 // can lead to loss of presentation data
283 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
284 {
285 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
286 }
287 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
288 {
289 aGroup->SetGroupPrimitivesAspect (aMarkerAsp);
290 }
291 }
292 }
293}
294
295//=======================================================================
296//function : SetMaterial
297//purpose :
298//=======================================================================
299void AIS_PointCloud::SetMaterial (const Graphic3d_NameOfMaterial theMatName)
300{
301 SetMaterial (Graphic3d_MaterialAspect (theMatName));
302}
303
304//=======================================================================
305//function : SetMaterial
306//purpose :
307//=======================================================================
308void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
309{
6262338c 310 if (!myDrawer->HasOwnShadingAspect())
d33222c1 311 {
312 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
6262338c 313 if (myDrawer->HasLink())
314 {
315 *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
316 }
d33222c1 317 }
318 hasOwnMaterial = Standard_True;
319
320 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
321 if (HasColor())
322 {
323 myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
324 }
325 myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
326
327 // modify shading presentation without re-computation
328 const PrsMgr_Presentations& aPrsList = Presentations();
329 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
330 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
331 {
332 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
333 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
334 {
335 continue;
336 }
337
338 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 339 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
340 {
341 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
342 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
343 {
344 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
345 }
346 }
347 }
348}
349
350//=======================================================================
351//function : UnsetMaterial
352//purpose :
353//=======================================================================
354void AIS_PointCloud::UnsetMaterial()
355{
356 if (!HasMaterial())
357 {
358 return;
359 }
360
361 if (HasColor()
362 || IsTransparent())
363 {
6262338c 364 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
365 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
366 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
367 aDefaultMat,
d33222c1 368 myCurrentFacingModel);
369 if (HasColor())
370 {
371 myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
372 myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
373 }
374 }
375 else
376 {
377 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
378 }
379 hasOwnMaterial = Standard_False;
380
381 // modify shading presentation without re-computation
382 const PrsMgr_Presentations& aPrsList = Presentations();
383 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
384 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
385 {
386 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
387 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
388 {
389 continue;
390 }
391
392 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
d33222c1 393 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
394 {
395 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
396 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
397 {
398 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
399 }
400 }
401 }
402}
403
404//=======================================================================
405//function : Compute
406//purpose :
407//=======================================================================
408void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
409 const Handle(Prs3d_Presentation)& thePrs,
410 const Standard_Integer theMode)
411{
412 thePrs->Clear();
413 switch (theMode)
414 {
415 case AIS_PointCloud::DM_Points:
416 {
417 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
418 if (aPoints.IsNull())
419 {
420 return;
421 }
422
d33222c1 423 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
2831708b 424 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
425 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
d33222c1 426 aGroup->AddPrimitiveArray (aPoints);
427 break;
428 }
429 case AIS_PointCloud::DM_BndBox:
430 {
431 Bnd_Box aBndBox = GetBoundingBox();
432 if (aBndBox.IsVoid())
433 {
434 return;
435 }
436
5ad8c033 437 StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer);
d33222c1 438 break;
439 }
440 }
441}
442
443//=======================================================================
444//function : ComputeSelection
445//purpose :
446//=======================================================================
447void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
8b9a309b 448 const Standard_Integer theMode)
d33222c1 449{
8b9a309b 450 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
451 switch (theMode)
452 {
453 case SM_Points:
454 {
455 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
456 if (!aPoints.IsNull()
457 && !aPoints->Attributes().IsNull())
458 {
459 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
460 aSensitive->SetSensitivityFactor (8);
461 aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location());
462 aSensitive->BVH();
463 theSelection->Add (aSensitive);
464 return;
465 }
466 break;
467 }
468 case SM_BndBox:
469 {
470 break;
471 }
472 default:
473 {
474 return;
475 }
476 }
477
d33222c1 478 Bnd_Box aBndBox = GetBoundingBox();
479 if (aBndBox.IsVoid())
480 {
481 return;
482 }
d33222c1 483 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
484 theSelection->Add (aSensBox);
485}