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 |
36 | IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud,AIS_InteractiveObject) |
37 | |
d33222c1 |
38 | //================================================== |
39 | // Function: AIS_PointCloud |
40 | // Purpose : Constructor |
41 | //================================================== |
42 | AIS_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 | //======================================================================= |
55 | const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const |
56 | { |
57 | return myPoints; |
58 | } |
59 | |
60 | //======================================================================= |
61 | //function : GetBoundingBox |
62 | //purpose : |
63 | //======================================================================= |
64 | Bnd_Box AIS_PointCloud::GetBoundingBox() const |
65 | { |
66 | return myBndBox; |
67 | } |
68 | |
69 | //! Auxiliary method |
70 | static 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 | //======================================================================= |
90 | void 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 | //======================================================================= |
100 | void 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 | //======================================================================= |
147 | void AIS_PointCloud::SetColor (const Quantity_NameOfColor theColor) |
148 | { |
149 | SetColor (Quantity_Color (theColor)); |
150 | } |
151 | |
152 | //======================================================================= |
153 | //function : SetColor |
154 | //purpose : |
155 | //======================================================================= |
156 | void 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 | //======================================================================= |
212 | void 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 | //======================================================================= |
299 | void AIS_PointCloud::SetMaterial (const Graphic3d_NameOfMaterial theMatName) |
300 | { |
301 | SetMaterial (Graphic3d_MaterialAspect (theMatName)); |
302 | } |
303 | |
304 | //======================================================================= |
305 | //function : SetMaterial |
306 | //purpose : |
307 | //======================================================================= |
308 | void 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 | //======================================================================= |
354 | void 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 | //======================================================================= |
408 | void 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 | //======================================================================= |
447 | void 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 | } |