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_Presentations.hxx>
28 #include <Select3D_SensitiveBox.hxx>
29 #include <Select3D_SensitivePrimitiveArray.hxx>
30 #include <SelectMgr_EntityOwner.hxx>
31 #include <SelectMgr_Selection.hxx>
32 #include <Prs3d_BndBox.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloudOwner, SelectMgr_EntityOwner)
35 IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject)
37 //=======================================================================
38 //function : AIS_PointCloudOwner
40 //=======================================================================
41 AIS_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())
49 //=======================================================================
50 //function : ~AIS_PointCloudOwner
52 //=======================================================================
53 AIS_PointCloudOwner::~AIS_PointCloudOwner()
58 //=======================================================================
59 //function : HilightWithColor
61 //=======================================================================
62 Standard_Boolean AIS_PointCloudOwner::IsForcedHilight() const
67 //=======================================================================
68 //function : HilightWithColor
70 //=======================================================================
71 void AIS_PointCloudOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
72 const Handle(Prs3d_Drawer)& theStyle,
73 const Standard_Integer )
75 Handle(AIS_PointCloud) anObj = Handle(AIS_PointCloud)::DownCast (Selectable());
78 throw Standard_ProgramError ("Internal Error within AIS_PointCloud::PointsOwner!");
81 const Handle(TColStd_HPackedMapOfInteger)& aMap = thePrsMgr->IsImmediateModeOn()
84 Handle(Prs3d_Presentation) aPrs = thePrsMgr->IsImmediateModeOn()
85 ? anObj->GetHilightPresentation(thePrsMgr)
86 : anObj->GetSelectPresentation (thePrsMgr);
87 const Graphic3d_ZLayerId aZLayer = theStyle->ZLayer() != -1
89 : (thePrsMgr->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : anObj->ZLayer());
90 aMap->ChangeMap().Clear();
91 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
93 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
94 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
96 const Handle(SelectMgr_SensitiveEntity)& aSelEnt = aSelEntIter.Value();
97 if (aSelEnt->BaseSensitive()->OwnerId() == this)
99 if (Handle(Select3D_SensitivePrimitiveArray) aSensitive = Handle(Select3D_SensitivePrimitiveArray)::DownCast (aSelEnt->BaseSensitive()))
101 aMap->ChangeMap() = aSensitive->LastDetectedElementMap()->Map();
102 if (aSensitive->LastDetectedElement() != -1)
104 aMap->ChangeMap().Add (aSensitive->LastDetectedElement());
113 if (aPrs->GetZLayer() != aZLayer)
115 aPrs->SetZLayer (aZLayer);
117 if (aMap->Map().IsEmpty())
122 const Handle(Graphic3d_ArrayOfPoints) anAllPoints = anObj->GetPoints();
123 if (anAllPoints.IsNull())
128 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (aMap->Map().Extent());
129 for (TColStd_PackedMapOfInteger::Iterator aPntIter (aMap->Map()); aPntIter.More(); aPntIter.Next())
131 const gp_Pnt aPnt = anAllPoints->Vertice (aPntIter.Key() + 1);
132 aPoints->AddVertex (aPnt);
135 Handle(Graphic3d_Group) aGroup = aPrs->NewGroup();
136 aGroup->SetGroupPrimitivesAspect (theStyle->PointAspect()->Aspect());
137 aGroup->AddPrimitiveArray (aPoints);
138 if (thePrsMgr->IsImmediateModeOn())
140 thePrsMgr->AddToImmediateList (aPrs);
148 //=======================================================================
149 //function : Unhilight
151 //=======================================================================
152 void AIS_PointCloudOwner::Unhilight (const Handle(PrsMgr_PresentationManager)& , const Standard_Integer )
154 if (Handle(Prs3d_Presentation) aPrs = Selectable()->GetSelectPresentation (Handle(PrsMgr_PresentationManager3d)()))
160 //=======================================================================
163 //=======================================================================
164 void AIS_PointCloudOwner::Clear (const Handle(PrsMgr_PresentationManager)& thePrsMgr, const Standard_Integer theMode)
166 SelectMgr_EntityOwner::Clear (thePrsMgr, theMode);
169 //==================================================
170 // Function: AIS_PointCloud
171 // Purpose : Constructor
172 //==================================================
173 AIS_PointCloud::AIS_PointCloud()
175 myDrawer->SetupOwnShadingAspect();
176 myDrawer->ShadingAspect()->Aspect()->SetMarkerType (Aspect_TOM_POINT);
178 SetDisplayMode (AIS_PointCloud::DM_Points);
179 SetHilightMode (AIS_PointCloud::DM_BndBox);
181 myDynHilightDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_PLUS, Quantity_NOC_CYAN1, 1.0));
184 //=======================================================================
185 //function : GetPoints
187 //=======================================================================
188 const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const
193 //=======================================================================
194 //function : GetBoundingBox
196 //=======================================================================
197 Bnd_Box AIS_PointCloud::GetBoundingBox() const
203 static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
206 if (thePoints.IsNull())
211 const Standard_Integer aNbVertices = thePoints->VertexNumber();
212 for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
214 aBndBox.Add (thePoints->Vertice (aVertIter));
219 //=======================================================================
220 //function : SetPoints
222 //=======================================================================
223 void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
225 myPoints = thePoints;
226 myBndBox = getBoundingBox (thePoints);
229 //=======================================================================
230 //function : SetPoints
232 //=======================================================================
233 void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
234 const Handle(Quantity_HArray1OfColor)& theColors,
235 const Handle(TColgp_HArray1OfDir)& theNormals)
239 if (theCoords.IsNull())
244 const Standard_Integer aNbPoints = theCoords->Length();
245 if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints)
246 || (!theColors.IsNull() && theColors->Length() != aNbPoints))
252 const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints;
253 const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints;
255 const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0;
256 const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0;
258 myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals);
259 for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter)
261 myPoints->AddVertex (theCoords->Value (aPntIter));
264 myPoints->SetVertexColor (myPoints->VertexNumber(),
265 theColors->Value (aPntIter + aDiffColors));
269 myPoints->SetVertexNormal (myPoints->VertexNumber(),
270 theNormals->Value (aPntIter + aDiffNormals));
273 myBndBox = getBoundingBox (myPoints);
276 //=======================================================================
277 //function : SetColor
279 //=======================================================================
280 void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
282 AIS_InteractiveObject::SetColor(theColor);
284 myDrawer->ShadingAspect()->SetColor (theColor);
285 SynchronizeAspects();
288 //=======================================================================
289 //function : UnsetColor
291 //=======================================================================
292 void AIS_PointCloud::UnsetColor()
299 AIS_InteractiveObject::UnsetColor();
301 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
302 Graphic3d_MaterialAspect aMat = aDefaultMat;
303 Quantity_Color aColor = aDefaultMat.Color();
304 if (myDrawer->HasLink())
306 aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
308 if (HasMaterial() || myDrawer->HasLink())
310 aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
314 aMat.SetColor (aColor);
318 Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
319 aMat.SetTransparency (Standard_ShortReal(aTransp));
321 myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
322 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
325 SynchronizeAspects();
328 //=======================================================================
329 //function : SetMaterial
331 //=======================================================================
332 void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
334 hasOwnMaterial = Standard_True;
336 myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
339 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
341 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
342 SynchronizeAspects();
345 //=======================================================================
346 //function : UnsetMaterial
348 //=======================================================================
349 void AIS_PointCloud::UnsetMaterial()
357 Graphic3d_MaterialAspect aDefaultMat (Graphic3d_NOM_BRASS);
358 myDrawer->ShadingAspect()->SetMaterial (myDrawer->HasLink() ?
359 myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel) :
361 myCurrentFacingModel);
364 myDrawer->ShadingAspect()->SetColor (myDrawer->Color(), myCurrentFacingModel);
365 myDrawer->ShadingAspect()->SetTransparency (myDrawer->Transparency(), myCurrentFacingModel);
368 hasOwnMaterial = Standard_False;
369 SynchronizeAspects();
372 //=======================================================================
375 //=======================================================================
376 void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
377 const Handle(Prs3d_Presentation)& thePrs,
378 const Standard_Integer theMode)
382 case AIS_PointCloud::DM_Points:
384 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
385 if (aPoints.IsNull())
390 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
391 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
392 aGroup->AddPrimitiveArray (aPoints);
395 case AIS_PointCloud::DM_BndBox:
397 Bnd_Box aBndBox = GetBoundingBox();
398 if (aBndBox.IsVoid())
403 Prs3d_BndBox::Add (thePrs, aBndBox, myDrawer);
409 //=======================================================================
410 //function : ComputeSelection
412 //=======================================================================
413 void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
414 const Standard_Integer theMode)
416 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
420 case SM_SubsetOfPoints:
422 const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
423 if (!aPoints.IsNull()
424 && !aPoints->Attributes().IsNull())
426 if (theMode == SM_SubsetOfPoints)
428 anOwner = new AIS_PointCloudOwner (this);
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);
439 theSelection->Add (aSensitive);
454 Bnd_Box aBndBox = GetBoundingBox();
455 if (aBndBox.IsVoid())
459 Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
460 theSelection->Add (aSensBox);