1 // Created on: 2014-08-13
2 // Created by: Maxim GLIBIN
3 // Copyright (c) 2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <AIS_PointCloud.hxx>
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_ModedPresentation.hxx>
28 #include <PrsMgr_Presentations.hxx>
29 #include <Select3D_SensitiveBox.hxx>
30 #include <Select3D_SensitivePrimitiveArray.hxx>
31 #include <SelectMgr_EntityOwner.hxx>
32 #include <SelectMgr_Selection.hxx>
33 #include <StdPrs_BndBox.hxx>
36 IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud,AIS_InteractiveObject)
38 //==================================================
39 // Function: AIS_PointCloud
40 // Purpose : Constructor
41 //==================================================
42 AIS_PointCloud::AIS_PointCloud()
44 SetDisplayMode (AIS_PointCloud::DM_Points);
45 SetHilightMode (AIS_PointCloud::DM_BndBox);
48 //=======================================================================
49 //function : GetPoints
51 //=======================================================================
52 const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const
57 //=======================================================================
58 //function : GetBoundingBox
60 //=======================================================================
61 Bnd_Box AIS_PointCloud::GetBoundingBox() const
67 static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
70 if (thePoints.IsNull())
75 const Standard_Integer aNbVertices = thePoints->VertexNumber();
76 for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
78 aBndBox.Add (thePoints->Vertice (aVertIter));
83 //=======================================================================
84 //function : SetPoints
86 //=======================================================================
87 void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
90 myBndBox = getBoundingBox (thePoints);
93 //=======================================================================
94 //function : SetPoints
96 //=======================================================================
97 void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
98 const Handle(Quantity_HArray1OfColor)& theColors,
99 const Handle(TColgp_HArray1OfDir)& theNormals)
103 if (theCoords.IsNull())
108 const Standard_Integer aNbPoints = theCoords->Length();
109 if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints)
110 || (!theColors.IsNull() && theColors->Length() != aNbPoints))
116 const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints;
117 const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints;
119 const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0;
120 const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0;
122 myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals);
123 for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter)
125 myPoints->AddVertex (theCoords->Value (aPntIter));
128 myPoints->SetVertexColor (myPoints->VertexNumber(),
129 theColors->Value (aPntIter + aDiffColors));
133 myPoints->SetVertexNormal (myPoints->VertexNumber(),
134 theNormals->Value (aPntIter + aDiffNormals));
137 myBndBox = getBoundingBox (myPoints);
140 //=======================================================================
141 //function : SetColor
143 //=======================================================================
144 void AIS_PointCloud::SetColor (const Quantity_NameOfColor theColor)
146 SetColor (Quantity_Color (theColor));
149 //=======================================================================
150 //function : SetColor
152 //=======================================================================
153 void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
155 AIS_InteractiveObject::SetColor(theColor);
157 if (!myDrawer->HasOwnPointAspect())
159 myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, theColor, 1.0));
160 if (myDrawer->HasLink())
162 *myDrawer->PointAspect()->Aspect() = *myDrawer->Link()->PointAspect()->Aspect();
165 if (!myDrawer->HasOwnShadingAspect())
167 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
168 if (myDrawer->HasLink())
170 *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
175 myDrawer->ShadingAspect()->SetColor (theColor);
176 myDrawer->PointAspect() ->SetColor (theColor);
178 const PrsMgr_Presentations& aPrsList = Presentations();
179 Handle(Graphic3d_AspectMarker3d) aPointAspect = myDrawer->PointAspect()->Aspect();
180 Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
181 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
183 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
184 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
189 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
191 // Set aspects for presentation
192 aPrs->SetPrimitivesAspect (aPointAspect);
193 aPrs->SetPrimitivesAspect (anAreaAspect);
195 // Go through all groups to change color for all primitives
196 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
198 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
199 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
201 aGroup->SetGroupPrimitivesAspect (aPointAspect);
203 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
205 aGroup->SetGroupPrimitivesAspect (anAreaAspect);
211 //=======================================================================
212 //function : UnsetColor
214 //=======================================================================
215 void AIS_PointCloud::UnsetColor()
222 AIS_InteractiveObject::UnsetColor();
226 myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
230 Quantity_Color aColor = Quantity_NOC_YELLOW;
231 Aspect_TypeOfMarker aType = Aspect_TOM_POINT;
232 Standard_Real aScale = 1.0;
233 if (myDrawer->HasLink())
235 myDrawer->Link()->PointAspect()->Aspect()->Values (aColor, aType, aScale);
237 myDrawer->PointAspect()->SetColor (aColor);
243 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
244 Graphic3d_MaterialAspect aMat = aDefaultMat;
245 if (HasMaterial() || myDrawer->HasLink())
247 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
251 Quantity_Color aColor = aDefaultMat.AmbientColor();
252 if (myDrawer->HasLink())
254 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
256 aMat.SetColor (aColor);
260 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
261 aMat.SetTransparency (aTransp);
263 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
267 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
269 myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
271 // modify shading presentation without re-computation
272 const PrsMgr_Presentations& aPrsList = Presentations();
273 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
274 Handle(Graphic3d_AspectMarker3d) aMarkerAsp = myDrawer->Link()->PointAspect()->Aspect();
275 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
277 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
278 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
283 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
284 aPrs->SetPrimitivesAspect (anAreaAsp);
285 aPrs->SetPrimitivesAspect (aMarkerAsp);
286 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
288 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
290 // Check if aspect of given type is set for the group,
291 // because setting aspect for group with no already set aspect
292 // can lead to loss of presentation data
293 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
295 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
297 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
299 aGroup->SetGroupPrimitivesAspect (aMarkerAsp);
305 //=======================================================================
306 //function : SetMaterial
308 //=======================================================================
309 void AIS_PointCloud::SetMaterial (const Graphic3d_NameOfMaterial theMatName)
311 SetMaterial (Graphic3d_MaterialAspect (theMatName));
314 //=======================================================================
315 //function : SetMaterial
317 //=======================================================================
318 void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
320 if (!myDrawer->HasOwnShadingAspect())
322 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
323 if (myDrawer->HasLink())
325 *myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
328 hasOwnMaterial = Standard_True;
330 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
333 myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
335 myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
337 // modify shading presentation without re-computation
338 const PrsMgr_Presentations& aPrsList = Presentations();
339 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
340 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
342 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
343 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
348 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
349 aPrs->SetPrimitivesAspect (anAreaAsp);
350 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
352 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
353 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
355 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
361 //=======================================================================
362 //function : UnsetMaterial
364 //=======================================================================
365 void AIS_PointCloud::UnsetMaterial()
375 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
376 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
377 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
379 myCurrentFacingModel);
382 myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
383 myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
388 myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
390 hasOwnMaterial = Standard_False;
392 // modify shading presentation without re-computation
393 const PrsMgr_Presentations& aPrsList = Presentations();
394 Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
395 for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
397 const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
398 if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
403 const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
404 aPrs->SetPrimitivesAspect (anAreaAsp);
405 for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
407 const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
408 if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
410 aGroup->SetGroupPrimitivesAspect (anAreaAsp);
416 //=======================================================================
419 //=======================================================================
420 void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
421 const Handle(Prs3d_Presentation)& thePrs,
422 const Standard_Integer theMode)
427 case AIS_PointCloud::DM_Points:
429 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
430 if (aPoints.IsNull())
435 Handle(Graphic3d_AspectMarker3d) aMarkerAspect = myDrawer->PointAspect()->Aspect();
436 if (!myDrawer->HasOwnPointAspect())
438 aMarkerAspect->SetType (Aspect_TOM_POINT);
441 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
442 aGroup->SetGroupPrimitivesAspect (aMarkerAspect);
443 aGroup->AddPrimitiveArray (aPoints);
446 case AIS_PointCloud::DM_BndBox:
448 Bnd_Box aBndBox = GetBoundingBox();
449 if (aBndBox.IsVoid())
454 StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer);
460 //=======================================================================
461 //function : ComputeSelection
463 //=======================================================================
464 void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
465 const Standard_Integer theMode)
467 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
472 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
473 if (!aPoints.IsNull()
474 && !aPoints->Attributes().IsNull())
476 Handle(Select3D_SensitivePrimitiveArray) aSensitive = new Select3D_SensitivePrimitiveArray (anOwner);
477 aSensitive->SetSensitivityFactor (8);
478 aSensitive->InitPoints (aPoints->Attributes(), aPoints->Indices(), TopLoc_Location());
480 theSelection->Add (aSensitive);
495 Bnd_Box aBndBox = GetBoundingBox();
496 if (aBndBox.IsVoid())
500 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
501 theSelection->Add (aSensBox);