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 |
33 | IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloudOwner, SelectMgr_EntityOwner) |
34 | IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject) |
d33222c1 |
35 | |
4a056d20 |
36 | //======================================================================= |
37 | //function : AIS_PointCloudOwner |
38 | //purpose : |
39 | //======================================================================= |
40 | AIS_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 | //======================================================================= |
52 | AIS_PointCloudOwner::~AIS_PointCloudOwner() |
53 | { |
54 | // |
55 | } |
56 | |
57 | //======================================================================= |
58 | //function : HilightWithColor |
59 | //purpose : |
60 | //======================================================================= |
61 | Standard_Boolean AIS_PointCloudOwner::IsForcedHilight() const |
62 | { |
63 | return true; |
64 | } |
65 | |
66 | //======================================================================= |
67 | //function : HilightWithColor |
68 | //purpose : |
69 | //======================================================================= |
70 | void AIS_PointCloudOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr, |
71 | const Handle(Prs3d_Drawer)& theStyle, |
72 | const Standard_Integer ) |
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 | //======================================================================= |
151 | void AIS_PointCloudOwner::Unhilight (const Handle(PrsMgr_PresentationManager)& , const Standard_Integer ) |
152 | { |
153 | if (Handle(Prs3d_Presentation) aPrs = Selectable()->GetSelectPresentation (Handle(PrsMgr_PresentationManager3d)())) |
154 | { |
155 | aPrs->Erase(); |
156 | } |
157 | } |
158 | |
159 | //======================================================================= |
160 | //function : Clear |
161 | //purpose : |
162 | //======================================================================= |
163 | void 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 | //================================================== |
172 | AIS_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 | //======================================================================= |
187 | const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const |
188 | { |
189 | return myPoints; |
190 | } |
191 | |
192 | //======================================================================= |
193 | //function : GetBoundingBox |
194 | //purpose : |
195 | //======================================================================= |
196 | Bnd_Box AIS_PointCloud::GetBoundingBox() const |
197 | { |
198 | return myBndBox; |
199 | } |
200 | |
201 | //! Auxiliary method |
202 | static 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 | //======================================================================= |
222 | void 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 | //======================================================================= |
232 | void 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 | //======================================================================= |
279 | void 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 | //======================================================================= |
291 | void 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 | //======================================================================= |
331 | void 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 | //======================================================================= |
348 | void 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 | //======================================================================= |
375 | void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/, |
376 | const Handle(Prs3d_Presentation)& thePrs, |
377 | const Standard_Integer theMode) |
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 | //======================================================================= |
412 | void 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 | } |