0030695: Visualization - selection by box should use clipping planes set for viewer...
[occt.git] / src / StdSelect / StdSelect_ViewerSelector3d.cxx
CommitLineData
b311480e 1// Created on: 1995-03-15
2// Created by: Robert COUBLANC
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
f751596e 17#include <StdSelect_ViewerSelector3d.hxx>
7fd59977 18#include <StdSelect.hxx>
0ef04197 19#include <Select3D_SensitiveEntity.hxx>
7fd59977 20#include <Graphic3d_AspectLine3d.hxx>
21#include <gp_Pnt.hxx>
22#include <gp_Lin.hxx>
23#include <gp_Pnt2d.hxx>
24#include <gp_Dir.hxx>
25#include <gp_Ax3.hxx>
26#include <gp_GTrsf.hxx>
4269bd1b 27#include <gp_Pln.hxx>
7fd59977 28#include <Select3D_SensitiveEntity.hxx>
b8ddfc2f 29#include <Graphic3d_ArrayOfPolylines.hxx>
f751596e 30#include <Graphic3d_Group.hxx>
51b10cd4 31#include <Graphic3d_SequenceOfHClipPlane.hxx>
f751596e 32#include <Graphic3d_Structure.hxx>
4269bd1b 33#include <SelectMgr_SelectableObject.hxx>
7fd59977 34#include <TColgp_HArray1OfPnt.hxx>
35#include <TColgp_Array1OfPnt.hxx>
f751596e 36#include <TColgp_Array1OfPnt2d.hxx>
7fd59977 37#include <TColgp_HArray1OfPnt2d.hxx>
38#include <Select3D_SensitiveCurve.hxx>
39#include <Select3D_SensitiveSegment.hxx>
40#include <Select3D_SensitiveFace.hxx>
41#include <Select3D_SensitiveCircle.hxx>
42#include <Select3D_SensitivePoint.hxx>
43#include <Select3D_SensitiveTriangulation.hxx>
44#include <Select3D_SensitiveTriangle.hxx>
45#include <Select3D_SensitiveWire.hxx>
7fd59977 46#include <Select3D_SensitiveBox.hxx>
f751596e 47#include <SelectMgr_Selection.hxx>
48#include <SelectMgr_EntityOwner.hxx>
7fd59977 49
679ecdee 50#include <Aspect_Grid.hxx>
7fd59977 51#include <Aspect_TypeOfMarker.hxx>
f751596e 52#include <Aspect_Window.hxx>
7fd59977 53#include <Graphic3d_AspectMarker3d.hxx>
a577aaab 54#include <Graphic3d_ArrayOfPoints.hxx>
decdee7d 55#include <math_BullardGenerator.hxx>
56#include <Message.hxx>
57#include <Message_Messenger.hxx>
58#include <Quantity_ColorHasher.hxx>
7fd59977 59#include <Poly_Connect.hxx>
60#include <TColStd_HArray1OfInteger.hxx>
61
62#include <Poly_Array1OfTriangle.hxx>
63#include <Poly_Triangulation.hxx>
64#include <OSD_Environment.hxx>
65#include <V3d.hxx>
66#include <V3d_View.hxx>
679ecdee 67#include <V3d_Viewer.hxx>
b8ddfc2f 68#include <TColgp_SequenceOfPnt.hxx>
69
f751596e 70#include <OSD_Timer.hxx>
71
f751596e 72
92efcf78 73IMPLEMENT_STANDARD_RTTIEXT(StdSelect_ViewerSelector3d,SelectMgr_ViewerSelector)
74
7fd59977 75static Standard_Integer StdSel_NumberOfFreeEdges (const Handle(Poly_Triangulation)& Trg)
76{
77 Standard_Integer nFree = 0;
78 Poly_Connect pc(Trg);
79 Standard_Integer t[3];
80 Standard_Integer i, j;
81 for (i = 1; i <= Trg->NbTriangles(); i++)
82 {
83 pc.Triangles (i, t[0], t[1], t[2]);
84 for (j = 0; j < 3; j++)
85 if (t[j] == 0) nFree++;
86 }
87 return nFree;
88}
89
197ac94e 90//=======================================================================
91// Function : Constructor
92// Purpose :
93//=======================================================================
f751596e 94StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() {}
3c982548 95
197ac94e 96//=======================================================================
3c982548 97// Function: SetPixelTolerance
98// Purpose :
197ac94e 99//=======================================================================
3bf9a45f 100void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance)
3c982548 101{
29a4908e 102 if (myTolerances.Tolerance() != theTolerance)
3c982548 103 {
3bf9a45f 104 if (theTolerance < 0)
28ee613b 105 myTolerances.ResetDefaults();
106 else
107 myTolerances.SetCustomTolerance (theTolerance);
197ac94e 108 myToUpdateTolerance = Standard_True;
3c982548 109 }
7fd59977 110}
111
197ac94e 112//=======================================================================
113// Function: Pick
7fd59977 114// Purpose :
197ac94e 115//=======================================================================
116void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
117 const Standard_Integer theYPix,
118 const Handle(V3d_View)& theView)
7fd59977 119{
1593b4ee 120 updateZLayers (theView);
f751596e 121 if(myToUpdateTolerance)
122 {
29a4908e 123 mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
f751596e 124 myToUpdateTolerance = Standard_False;
125 }
126
127 mySelectingVolumeMgr.SetCamera (theView->Camera());
128 mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Point);
129 Standard_Integer aWidth = 0, aHeight = 0;
130 theView->Window()->Size (aWidth, aHeight);
131 mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
132 gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
133 static_cast<Standard_Real> (theYPix));
134 mySelectingVolumeMgr.BuildSelectingVolume (aMousePos);
fe525c6f 135 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
7fd59977 136
f751596e 137 TraverseSensitives();
197ac94e 138}
7fd59977 139
197ac94e 140//=======================================================================
141// Function: Pick
7fd59977 142// Purpose :
197ac94e 143//=======================================================================
144void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPMin,
145 const Standard_Integer theYPMin,
146 const Standard_Integer theXPMax,
147 const Standard_Integer theYPMax,
148 const Handle(V3d_View)& theView)
7fd59977 149{
1593b4ee 150 updateZLayers (theView);
f751596e 151 mySelectingVolumeMgr.SetCamera (theView->Camera());
152 mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Box);
153 Standard_Integer aWidth = 0, aHeight = 0;
154 theView->Window()->Size (aWidth, aHeight);
155 mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
156 gp_Pnt2d aMinMousePos (static_cast<Standard_Real> (theXPMin),
157 static_cast<Standard_Real> (theYPMin));
158 gp_Pnt2d aMaxMousePos (static_cast<Standard_Real> (theXPMax),
159 static_cast<Standard_Real> (theYPMax));
160 mySelectingVolumeMgr.BuildSelectingVolume (aMinMousePos,
161 aMaxMousePos);
162
8996b449 163 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
164
f751596e 165 TraverseSensitives();
7fd59977 166}
167
197ac94e 168//=======================================================================
7fd59977 169// Function: Pick
170// Purpose : Selection using a polyline
197ac94e 171//=======================================================================
172void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
173 const Handle(V3d_View)& theView)
7fd59977 174{
1593b4ee 175 updateZLayers (theView);
f751596e 176 mySelectingVolumeMgr.SetCamera (theView->Camera());
177 mySelectingVolumeMgr.SetActiveSelectionType (SelectMgr_SelectingVolumeManager::Polyline);
178 Standard_Integer aWidth = 0, aHeight = 0;
179 theView->Window()->Size (aWidth, aHeight);
180 mySelectingVolumeMgr.SetWindowSize (aWidth, aHeight);
181 mySelectingVolumeMgr.BuildSelectingVolume (thePolyline);
182
8996b449 183 mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
184
f751596e 185 TraverseSensitives();
7fd59977 186}
187
197ac94e 188//=======================================================================
7fd59977 189// Function: DisplaySensitive.
190// Purpose : Display active primitives.
197ac94e 191//=======================================================================
192void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
7fd59977 193{
b5cce1ab 194 for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
197ac94e 195 {
c357e426 196 Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
b5cce1ab 197 const Handle (SelectMgr_SelectableObject)& anObj = aSelectableIt.Value();
198 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
7fd59977 199 {
b5cce1ab 200 if (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated)
f751596e 201 {
b5cce1ab 202 computeSensitivePrs (aStruct, aSelIter.Value(), anObj->Transformation(), Handle(Graphic3d_TransformPers)());
f751596e 203 }
7fd59977 204 }
825aa485 205
206 myStructs.Append (aStruct);
7fd59977 207 }
7fd59977 208
b5cce1ab 209 for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
825aa485 210 {
b5cce1ab 211 Handle(Graphic3d_Structure)& aStruct = aStructIter.ChangeValue();
825aa485 212 aStruct->SetDisplayPriority (10);
213 aStruct->Display();
214 }
197ac94e 215
679ecdee 216 theView->Update();
7fd59977 217}
218
197ac94e 219//=======================================================================
7fd59977 220// Function: ClearSensitive
221// Purpose :
197ac94e 222//=======================================================================
223void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
7fd59977 224{
b5cce1ab 225 for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
197ac94e 226 {
b5cce1ab 227 aStructIter.ChangeValue()->Remove();
197ac94e 228 }
825aa485 229 myStructs.Clear();
7fd59977 230
825aa485 231 if (!theView.IsNull())
197ac94e 232 {
825aa485 233 theView->Update();
197ac94e 234 }
7fd59977 235}
236
237//=======================================================================
238//function : DisplaySenstive
239//purpose :
240//=======================================================================
197ac94e 241void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
f751596e 242 const gp_Trsf& theTrsf,
197ac94e 243 const Handle(V3d_View)& theView,
244 const Standard_Boolean theToClearOthers)
7fd59977 245{
197ac94e 246 if (theToClearOthers)
247 {
825aa485 248 ClearSensitive (theView);
197ac94e 249 }
7fd59977 250
c357e426 251 Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
7fd59977 252
778cd667 253 computeSensitivePrs (aStruct, theSel, theTrsf, Handle(Graphic3d_TransformPers)());
825aa485 254
255 myStructs.Append (aStruct);
256 myStructs.Last()->SetDisplayPriority (10);
257 myStructs.Last()->Display();
7fd59977 258
679ecdee 259 theView->Update();
7fd59977 260}
261
262//=======================================================================
1593b4ee 263//function : computeSensitivePrs
7fd59977 264//purpose :
265//=======================================================================
1593b4ee 266void StdSelect_ViewerSelector3d::computeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
825aa485 267 const Handle(SelectMgr_Selection)& theSel,
268 const gp_Trsf& theLoc,
778cd667 269 const Handle(Graphic3d_TransformPers)& theTrsfPers)
7fd59977 270{
778cd667 271 theStructure->SetTransformPersistence (theTrsfPers);
825aa485 272
273 Handle(Graphic3d_Group) aSensGroup = theStructure->NewGroup();
274
275 Quantity_Color aColor (Quantity_NOC_INDIANRED3);
b5cce1ab 276 Handle(Graphic3d_AspectMarker3d) aMarkerAspect =new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
825aa485 277
278 aSensGroup->SetPrimitivesAspect (aMarkerAspect);
b5cce1ab 279 aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
825aa485 280
281 Handle(Graphic3d_Group) anAreaGroup = theStructure->NewGroup();
282
b5cce1ab 283 anAreaGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
825aa485 284
b8ddfc2f 285 TColgp_SequenceOfPnt aSeqLines, aSeqFree;
286 TColStd_SequenceOfInteger aSeqBnds;
b5cce1ab 287 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
7fd59977 288 {
0ef04197 289 const Handle(Select3D_SensitiveEntity)& Ent = aSelEntIter.Value()->BaseSensitive();
f751596e 290 const Standard_Boolean hasloc = theLoc.Form() != gp_Identity;
7fd59977 291
292 //==============
293 // Box
294 //=============
295
296 if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveBox))
297 {
298 const Bnd_Box& B = Handle(Select3D_SensitiveBox)::DownCast (Ent)->Box();
299 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
300 B.Get (xmin, ymin, zmin, xmax, ymax, zmax);
b8ddfc2f 301 Standard_Integer i;
7fd59977 302 gp_Pnt theboxpoint[8] =
303 {
304 gp_Pnt(xmin,ymin,zmin),
305 gp_Pnt(xmax,ymin,zmin),
306 gp_Pnt(xmax,ymax,zmin),
307 gp_Pnt(xmin,ymax,zmin),
308 gp_Pnt(xmin,ymin,zmax),
309 gp_Pnt(xmax,ymin,zmax),
310 gp_Pnt(xmax,ymax,zmax),
311 gp_Pnt(xmin,ymax,zmax)
312 };
313 if(hasloc)
314 {
b8ddfc2f 315 for (i = 0; i <= 7; i++)
f751596e 316 theboxpoint[i].Transform (theLoc);
7fd59977 317 }
7fd59977 318
b8ddfc2f 319 aSeqBnds.Append(5);
320 for (i = 0; i < 4; i++)
321 aSeqLines.Append(theboxpoint[i]);
322 aSeqLines.Append(theboxpoint[0]);
323
324 aSeqBnds.Append(5);
325 for (i = 4; i < 8; i++)
326 aSeqLines.Append(theboxpoint[i]);
327 aSeqLines.Append(theboxpoint[4]);
7fd59977 328
b8ddfc2f 329 for (i = 0; i < 4; i++)
7fd59977 330 {
b8ddfc2f 331 aSeqBnds.Append(2);
332 aSeqLines.Append(theboxpoint[i]);
333 aSeqLines.Append(theboxpoint[i+4]);
7fd59977 334 }
335 }
336 //==============
337 // Face
338 //=============
339 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveFace))
340 {
341 Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(Ent);
342 Handle(TColgp_HArray1OfPnt) TheHPts;
f751596e 343 aFace->GetPoints(TheHPts);
7fd59977 344 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
345
b8ddfc2f 346 aSeqBnds.Append(ThePts.Length());
7fd59977 347 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
348 {
349 if (hasloc)
f751596e 350 aSeqLines.Append(ThePts(I).Transformed (theLoc));
7fd59977 351 else
b8ddfc2f 352 aSeqLines.Append(ThePts(I));
7fd59977 353 }
7fd59977 354 }
355 //==============
356 // Curve
357 //=============
358 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
359 {
360 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(Ent);
361 Handle(TColgp_HArray1OfPnt) TheHPts;
362 aCurve->Points3D(TheHPts);
363 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
364
b8ddfc2f 365 aSeqBnds.Append(ThePts.Length());
7fd59977 366 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
367 {
368 if (hasloc)
f751596e 369 aSeqLines.Append(ThePts(I).Transformed (theLoc));
7fd59977 370 else
b8ddfc2f 371 aSeqLines.Append(ThePts(I));
7fd59977 372 }
7fd59977 373 }
374 //==============
375 // Wire
376 //=============
377 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
378 {
b8ddfc2f 379 Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
f751596e 380 const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& anEntities = aWire->GetEdges();
7fd59977 381
f751596e 382 for (int i = 0; i < anEntities.Length(); i++)
7fd59977 383 {
a9dde4a3 384 Handle(Select3D_SensitiveEntity) SubEnt = anEntities.Value(i);
7fd59977 385
386 //Segment
387 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
388 {
7fd59977 389 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->StartPoint().XYZ());
390 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(SubEnt)->EndPoint().XYZ());
391 if (hasloc)
392 {
f751596e 393 P1.Transform(theLoc);
394 P2.Transform(theLoc);
7fd59977 395 }
b8ddfc2f 396 aSeqBnds.Append(2);
397 aSeqLines.Append(P1);
398 aSeqLines.Append(P2);
7fd59977 399 }
400
401 //circle
402 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
403 {
d7515f9a 404 Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(SubEnt);
405 Standard_Integer aFrom, aTo;
406 aCircle->ArrayBounds (aFrom, aTo);
407 aTo -= 2;
408 for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
7fd59977 409 {
d7515f9a 410 gp_Pnt aPnts[3] =
7fd59977 411 {
d7515f9a 412 gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
413 gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
414 gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
7fd59977 415 };
416
417 if (hasloc)
418 {
f751596e 419 aPnts[0].Transform (theLoc);
420 aPnts[1].Transform (theLoc);
421 aPnts[2].Transform (theLoc);
7fd59977 422 }
423
d7515f9a 424 aSeqBnds.Append (4);
425 aSeqLines.Append (aPnts[0]);
426 aSeqLines.Append (aPnts[1]);
427 aSeqLines.Append (aPnts[2]);
428 aSeqLines.Append (aPnts[0]);
7fd59977 429 }
430 }
431
432 //curve
433 if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCurve))
434 {
435 Handle(Select3D_SensitiveCurve) aCurve = Handle(Select3D_SensitiveCurve)::DownCast(SubEnt);
436 Handle(TColgp_HArray1OfPnt) TheHPts;
437 aCurve->Points3D (TheHPts);
438 const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
b8ddfc2f 439
440 aSeqBnds.Append(ThePts.Length());
7fd59977 441 for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
442 {
443 if (hasloc)
f751596e 444 aSeqLines.Append(ThePts(I).Transformed (theLoc));
7fd59977 445 else
b8ddfc2f 446 aSeqLines.Append(ThePts(I));
7fd59977 447 }
7fd59977 448 }
449 }
450 }
451 //==============
452 // Segment
453 //=============
454 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
455 {
7fd59977 456 gp_Pnt P1 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->StartPoint().XYZ());
457 gp_Pnt P2 (Handle(Select3D_SensitiveSegment)::DownCast(Ent)->EndPoint().XYZ());
458 if (hasloc)
459 {
f751596e 460 P1.Transform (theLoc);
461 P2.Transform (theLoc);
7fd59977 462 }
b8ddfc2f 463 aSeqBnds.Append(2);
464 aSeqLines.Append(P1);
465 aSeqLines.Append(P2);
7fd59977 466 }
467 //==============
468 // Circle
469 //=============
470 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
471 {
d7515f9a 472 Handle(Select3D_SensitiveCircle) aCircle = Handle(Select3D_SensitiveCircle)::DownCast(Ent);
473 Standard_Integer aFrom, aTo;
474 aCircle->ArrayBounds (aFrom, aTo);
475 aTo -= 2;
476 for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; aPntIter += 2)
7fd59977 477 {
d7515f9a 478 gp_Pnt aPnts[3] =
7fd59977 479 {
d7515f9a 480 gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
481 gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
482 gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
7fd59977 483 };
484
485 if (hasloc)
486 {
f751596e 487 aPnts[0].Transform (theLoc);
488 aPnts[1].Transform (theLoc);
489 aPnts[2].Transform (theLoc);
7fd59977 490 }
491
d7515f9a 492 aSeqBnds.Append (4);
493 aSeqLines.Append (aPnts[0]);
494 aSeqLines.Append (aPnts[1]);
495 aSeqLines.Append (aPnts[2]);
496 aSeqLines.Append (aPnts[0]);
7fd59977 497 }
498 }
499 //==============
500 // Point
501 //=============
502 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitivePoint))
503 {
504 gp_Pnt P = hasloc ?
505 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point() :
f751596e 506 Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theLoc);
a577aaab 507 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
508 anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
825aa485 509 aSensGroup->AddPrimitiveArray (anArrayOfPoints);
7fd59977 510 }
511 //============================================================
512 // Triangulation : On met un petit offset ves l'interieur...
513 //==========================================================
514 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
515 {
c5f3a425 516 Handle(Poly_Triangulation) PT (Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->Triangulation());
7fd59977 517
518 const Poly_Array1OfTriangle& triangles = PT->Triangles();
519 const TColgp_Array1OfPnt& Nodes = PT->Nodes();
7fd59977 520 Standard_Integer n[3];
7fd59977 521
522 TopLoc_Location iloc, bidloc;
c5f3a425 523 if (Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->HasInitLocation())
524 bidloc = Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->GetInitLocation();
7fd59977 525
526 if (bidloc.IsIdentity())
f751596e 527 iloc = theLoc;
7fd59977 528 else
f751596e 529 iloc = theLoc * bidloc;
7fd59977 530
531 Standard_Integer i;
532 for (i = 1; i <= PT->NbTriangles(); i++)
533 {
534 triangles (i).Get (n[0], n[1], n[2]);
535 gp_Pnt P1 (Nodes (n[0]).Transformed (iloc));
536 gp_Pnt P2 (Nodes (n[1]).Transformed (iloc));
537 gp_Pnt P3 (Nodes (n[2]).Transformed (iloc));
538 gp_XYZ V1 (P1.XYZ());
539 gp_XYZ V2 (P2.XYZ());
540 gp_XYZ V3 (P3.XYZ());
541 gp_XYZ CDG (P1.XYZ()); CDG += (P2.XYZ()); CDG += (P3.XYZ()); CDG /= 3.0;
7fd59977 542 V1 -= CDG; V2 -= CDG; V3 -= CDG;
7fd59977 543 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
544 V1 += CDG; V2 += CDG; V3 += CDG;
b8ddfc2f 545
546 aSeqBnds.Append(4);
547 aSeqLines.Append(gp_Pnt(V1));
548 aSeqLines.Append(gp_Pnt(V2));
549 aSeqLines.Append(gp_Pnt(V3));
550 aSeqLines.Append(gp_Pnt(V1));
7fd59977 551 }
552
553 // recherche des bords libres...
554
555 Handle(TColStd_HArray1OfInteger) FreeEdges = new TColStd_HArray1OfInteger (1, 2 * StdSel_NumberOfFreeEdges (PT));
556 TColStd_Array1OfInteger& FreeE = FreeEdges->ChangeArray1();
557 Poly_Connect pc (PT);
558 Standard_Integer t[3];
559 Standard_Integer j;
560 Standard_Integer fr (1);
561 for (i = 1; i <= PT->NbTriangles(); i++)
562 {
563 pc.Triangles (i, t[0], t[1], t[2]);
564 triangles (i).Get (n[0], n[1], n[2]);
565 for (j = 0; j < 3; j++)
566 {
567 Standard_Integer k = (j + 1) % 3;
568 if (t[j] == 0)
569 {
570 FreeE (fr) = n[j];
571 FreeE (fr + 1)= n[k];
572 fr += 2;
573 }
574 }
575 }
7fd59977 576 for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
577 {
b8ddfc2f 578 gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
579 aSeqFree.Append(pe1);
580 aSeqFree.Append(pe2);
7fd59977 581 }
7fd59977 582 }
583 else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
584 {
585 Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
b8ddfc2f 586 gp_Pnt P1, P2, P3;
7fd59977 587 Str->Points3D (P1, P2, P3);
b8ddfc2f 588 gp_Pnt CDG = Str->Center3D();
7fd59977 589
590 gp_XYZ V1 (P1.XYZ()); V1 -= (CDG.XYZ());
591 gp_XYZ V2 (P2.XYZ()); V2 -= (CDG.XYZ());
592 gp_XYZ V3 (P3.XYZ()); V3 -= (CDG.XYZ());
7fd59977 593 V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
594 V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
b8ddfc2f 595
596 aSeqBnds.Append(4);
597 aSeqLines.Append(gp_Pnt(V1));
598 aSeqLines.Append(gp_Pnt(V2));
599 aSeqLines.Append(gp_Pnt(V3));
600 aSeqLines.Append(gp_Pnt(V1));
7fd59977 601 }
602 }
b8ddfc2f 603
604 Standard_Integer i;
605
606 if (aSeqLines.Length())
607 {
608 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqLines.Length(),aSeqBnds.Length());
609 for (i = 1; i <= aSeqLines.Length(); i++)
610 aPrims->AddVertex(aSeqLines(i));
611 for (i = 1; i <= aSeqBnds.Length(); i++)
612 aPrims->AddBound(aSeqBnds(i));
825aa485 613 anAreaGroup->AddPrimitiveArray(aPrims);
b8ddfc2f 614 }
615
616 if (aSeqFree.Length())
617 {
825aa485 618 aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
b8ddfc2f 619 Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
620 for (i = 1; i <= aSeqFree.Length(); i++)
197ac94e 621 {
b8ddfc2f 622 aPrims->AddBound(2);
623 aPrims->AddVertex(aSeqLines(i++));
624 aPrims->AddVertex(aSeqLines(i));
197ac94e 625 }
825aa485 626 aSensGroup->AddPrimitiveArray(aPrims);
627 aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
b8ddfc2f 628 }
7fd59977 629}
630
1593b4ee 631//=======================================================================
632// Function: updateZLayers
633// Purpose :
634//=======================================================================
635void StdSelect_ViewerSelector3d::updateZLayers (const Handle(V3d_View)& theView)
636{
637 myZLayerOrderMap.Clear();
638 TColStd_SequenceOfInteger aZLayers;
639 theView->Viewer()->GetAllZLayers (aZLayers);
640 Standard_Integer aPos = 0;
641 Standard_Boolean isPrevDepthWrite = true;
642 for (TColStd_SequenceOfInteger::Iterator aLayerIter (aZLayers); aLayerIter.More(); aLayerIter.Next())
643 {
644 Graphic3d_ZLayerSettings aSettings = theView->Viewer()->ZLayerSettings (aLayerIter.Value());
7c3ef2f7 645 if (aSettings.ToClearDepth()
646 || isPrevDepthWrite != aSettings.ToEnableDepthWrite())
1593b4ee 647 {
648 ++aPos;
649 }
7c3ef2f7 650 isPrevDepthWrite = aSettings.ToEnableDepthWrite();
1593b4ee 651 myZLayerOrderMap.Bind (aLayerIter.Value(), aPos);
652 }
653}
decdee7d 654
655namespace
656{
657 //! Abstract class for filling pixel with color.
658 class BaseFiller : public Standard_Transient
659 {
660 DEFINE_STANDARD_RTTI_INLINE(BaseFiller, Standard_Transient)
661 public:
662
663 //! Main constructor.
664 BaseFiller (Image_PixMap& thePixMap,
665 StdSelect_ViewerSelector3d* theSelector)
666 : myImage (&thePixMap),
667 myMainSel(theSelector) {}
668
669 //! Fill pixel at specified position.
670 virtual void Fill (const Standard_Integer theCol,
671 const Standard_Integer theRow,
672 const Standard_Integer thePicked) = 0;
673
674 //! Flush results into final image.
675 virtual void Flush() {}
676
677 protected:
678
679 //! Find the new unique random color.
680 void randomPastelColor (Quantity_Color& theColor)
681 {
682 for (;;)
683 {
684 nextRandomPastelColor (theColor);
685 if (myUniqueColors.Add (theColor))
686 {
687 return;
688 }
689 }
690 }
691
692 //! Fills the given color as random.
693 void nextRandomPastelColor (Quantity_Color& theColor)
694 {
695 theColor = Quantity_Color (Standard_Real(myBullardGenerator.NextInt() % 256) / 255.0,
696 Standard_Real(myBullardGenerator.NextInt() % 256) / 255.0,
697 Standard_Real(myBullardGenerator.NextInt() % 256) / 255.0,
698 Quantity_TOC_RGB);
699 }
700
701 protected:
702 Image_PixMap* myImage;
703 StdSelect_ViewerSelector3d* myMainSel;
704 math_BullardGenerator myBullardGenerator;
705 NCollection_Map<Quantity_Color, Quantity_ColorHasher> myUniqueColors;
706 };
707
708 //! Help class for filling pixel with random color.
709 class GeneratedEntityColorFiller : public BaseFiller
710 {
711 DEFINE_STANDARD_RTTI_INLINE(GeneratedEntityColorFiller, BaseFiller)
712 public:
713 GeneratedEntityColorFiller (Image_PixMap& thePixMap,
714 StdSelect_ViewerSelector3d* theSelector,
715 const SelectMgr_SelectableObjectSet& theSelObjects)
716 : BaseFiller (thePixMap, theSelector)
717 {
718 // generate per-entity colors in the order as they have been activated
719 for (SelectMgr_SelectableObjectSet::Iterator anObjIter (theSelObjects); anObjIter.More(); anObjIter.Next())
720 {
721 const Handle(SelectMgr_SelectableObject)& anObj = anObjIter.Value();
b5cce1ab 722 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
decdee7d 723 {
b5cce1ab 724 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
725 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
decdee7d 726 {
b5cce1ab 727 const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
decdee7d 728 if (!myMapEntityColors.IsBound (aSens->BaseSensitive()))
729 {
730 Quantity_Color aColor;
731 randomPastelColor (aColor);
732 myMapEntityColors.Bind (aSens->BaseSensitive(), aColor);
733 }
734 }
735 }
736 }
737 }
738
739 virtual void Fill (const Standard_Integer theCol,
740 const Standard_Integer theRow,
741 const Standard_Integer thePicked) Standard_OVERRIDE
742 {
743 if (thePicked < 1
744 || thePicked > myMainSel->NbPicked())
745 {
746 myImage->SetPixelColor (theCol, theRow, Quantity_Color(Quantity_NOC_BLACK));
747 return;
748 }
749
0ef04197 750 const Handle(Select3D_SensitiveEntity)& aPickedEntity = myMainSel->PickedEntity (thePicked);
decdee7d 751 Quantity_Color aColor (Quantity_NOC_BLACK);
752 myMapEntityColors.Find (aPickedEntity, aColor);
753 myImage->SetPixelColor (theCol, theRow, aColor);
754 }
755
756 protected:
0ef04197 757 NCollection_DataMap<Handle(Select3D_SensitiveEntity), Quantity_Color> myMapEntityColors;
decdee7d 758 };
759
760 //! Help class for filling pixel with normalized depth of ray.
761 class NormalizedDepthFiller : public BaseFiller
762 {
763 DEFINE_STANDARD_RTTI_INLINE(NormalizedDepthFiller, BaseFiller)
764 public:
765 NormalizedDepthFiller (Image_PixMap& thePixMap,
766 StdSelect_ViewerSelector3d* theSelector,
767 const Standard_Boolean theToInverse)
768 : BaseFiller (thePixMap, theSelector),
769 myDepthMin ( RealLast()),
770 myDepthMax (-RealLast()),
771 myToInverse(theToInverse)
772 {
dc858f4c 773 myUnnormImage.InitZero (Image_Format_GrayF, thePixMap.SizeX(), thePixMap.SizeY());
decdee7d 774 }
775
776 //! Accumulate the data.
777 virtual void Fill (const Standard_Integer theCol,
778 const Standard_Integer theRow,
779 const Standard_Integer thePicked) Standard_OVERRIDE
780 {
781 if (myUnnormImage.IsEmpty())
782 {
783 return;
784 }
785
786 if (thePicked < 1
787 || thePicked > myMainSel->NbPicked())
788 {
789 myUnnormImage.ChangeValue<float> (theRow, theCol) = ShortRealLast();
790 return;
791 }
792
793 const SelectMgr_SortCriterion& aSortCriterion = myMainSel->PickedData (thePicked);
794 myUnnormImage.ChangeValue<float> (theRow, theCol) = float(aSortCriterion.Depth);
795 myDepthMin = Min (myDepthMin, aSortCriterion.Depth);
796 myDepthMax = Max (myDepthMax, aSortCriterion.Depth);
797 }
798
799 //! Normalize the depth values.
800 virtual void Flush() Standard_OVERRIDE
801 {
21b2385f 802 float aFrom = 0.0f;
803 float aDelta = 1.0f;
decdee7d 804 if (myDepthMin <= myDepthMax)
805 {
21b2385f 806 aFrom = float(myDepthMin);
807 aDelta = float(myDepthMax) - float(myDepthMin);
808 if (aDelta <= ShortRealEpsilon())
decdee7d 809 {
21b2385f 810 aDelta = 1.0f;
decdee7d 811 }
812 }
813 for (Standard_Size aRowIter = 0; aRowIter < myUnnormImage.SizeY(); ++aRowIter)
814 {
815 for (Standard_Size aColIter = 0; aColIter < myUnnormImage.SizeX(); ++aColIter)
816 {
817 float aDepth = myUnnormImage.Value<float> (aRowIter, aColIter);
818 if (aDepth <= -ShortRealLast()
819 || aDepth >= ShortRealLast())
820 {
821 myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
e958a649 822 Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
decdee7d 823 continue;
824 }
825
21b2385f 826 float aNormDepth = (aDepth - aFrom) / aDelta;
decdee7d 827 if (myToInverse)
828 {
829 aNormDepth = 1.0f - aNormDepth;
830 }
831 myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
e958a649 832 Quantity_ColorRGBA (aNormDepth, aNormDepth, aNormDepth, 1.0f));
decdee7d 833 }
834 }
835 }
836
837 private:
838 Image_PixMap myUnnormImage;
839 Standard_Real myDepthMin;
840 Standard_Real myDepthMax;
841 Standard_Boolean myToInverse;
842 };
843
844 //! Help class for filling pixel with unnormalized depth of ray.
845 class UnnormalizedDepthFiller : public BaseFiller
846 {
847 DEFINE_STANDARD_RTTI_INLINE(UnnormalizedDepthFiller, BaseFiller)
848 public:
849 UnnormalizedDepthFiller (Image_PixMap& thePixMap,
850 StdSelect_ViewerSelector3d* theSelector)
851 : BaseFiller (thePixMap, theSelector) {}
852
853 virtual void Fill (const Standard_Integer theCol,
854 const Standard_Integer theRow,
855 const Standard_Integer thePicked) Standard_OVERRIDE
856 {
857 if (thePicked < 1
858 || thePicked > myMainSel->NbPicked())
859 {
e958a649 860 myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
decdee7d 861 return;
862 }
863
864 const SelectMgr_SortCriterion& aSortCriterion = myMainSel->PickedData (thePicked);
865 const float aDepth = float(aSortCriterion.Depth);
21b2385f 866 myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (Graphic3d_Vec4 (aDepth, aDepth, aDepth, 1.0f)));
decdee7d 867 }
868 };
869
870 //! Help class for filling pixel with color of detected object.
871 class GeneratedOwnerColorFiller : public BaseFiller
872 {
873 DEFINE_STANDARD_RTTI_INLINE(GeneratedOwnerColorFiller, BaseFiller)
874 public:
875 GeneratedOwnerColorFiller (Image_PixMap& thePixMap,
876 StdSelect_ViewerSelector3d* theSelector,
877 const SelectMgr_SelectableObjectSet& theSelObjects)
878 : BaseFiller (thePixMap, theSelector)
879 {
880 // generate per-owner colors in the order as they have been activated
881 for (SelectMgr_SelectableObjectSet::Iterator anObjIter (theSelObjects); anObjIter.More(); anObjIter.Next())
882 {
883 const Handle(SelectMgr_SelectableObject)& anObj = anObjIter.Value();
b5cce1ab 884 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
decdee7d 885 {
b5cce1ab 886 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
887 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
decdee7d 888 {
b5cce1ab 889 const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
decdee7d 890 const Handle(SelectBasics_EntityOwner)& anOwner = aSens->BaseSensitive()->OwnerId();
891 if (!myMapOwnerColors.IsBound (anOwner))
892 {
893 Quantity_Color aColor;
894 randomPastelColor (aColor);
895 myMapOwnerColors.Bind (anOwner, aColor);
896 }
897 }
898 }
899 }
900 }
901
902 virtual void Fill (const Standard_Integer theCol,
903 const Standard_Integer theRow,
904 const Standard_Integer thePicked) Standard_OVERRIDE
905 {
906 if (thePicked < 1
907 || thePicked > myMainSel->NbPicked())
908 {
909 myImage->SetPixelColor (theCol, theRow, Quantity_Color(Quantity_NOC_BLACK));
910 return;
911 }
912
913 const Handle(SelectMgr_EntityOwner)& aPickedOwner = myMainSel->Picked (thePicked);
914 Quantity_Color aColor (Quantity_NOC_BLACK);
915 myMapOwnerColors.Find (aPickedOwner, aColor);
916 myImage->SetPixelColor (theCol, theRow, aColor);
917 }
918
919 protected:
920 NCollection_DataMap<Handle(SelectBasics_EntityOwner), Quantity_Color> myMapOwnerColors;
921 };
922
923 //! Help class for filling pixel with random color for each selection mode.
924 class GeneratedSelModeColorFiller : public BaseFiller
925 {
926 DEFINE_STANDARD_RTTI_INLINE(GeneratedSelModeColorFiller, BaseFiller)
927 public:
928 GeneratedSelModeColorFiller (Image_PixMap& thePixMap,
929 StdSelect_ViewerSelector3d* theSelector)
930 : BaseFiller (thePixMap, theSelector)
931 {
932 // generate standard modes in proper order, consider custom objects would use similar scheme
933 myMapSelectionModeColors.Bind ( 0, Quantity_NOC_WHITE); // default (entire object selection)
934 myMapSelectionModeColors.Bind ( 1, Quantity_NOC_YELLOW); // TopAbs_VERTEX
935 myMapSelectionModeColors.Bind ( 2, Quantity_NOC_GREEN); // TopAbs_EDGE
936 myMapSelectionModeColors.Bind ( 3, Quantity_NOC_RED); // TopAbs_WIRE
937 myMapSelectionModeColors.Bind ( 4, Quantity_NOC_BLUE1); // TopAbs_FACE
938 myMapSelectionModeColors.Bind ( 5, Quantity_NOC_CYAN1); // TopAbs_SHELL
939 myMapSelectionModeColors.Bind ( 6, Quantity_NOC_PURPLE); // TopAbs_SOLID
940 myMapSelectionModeColors.Bind ( 7, Quantity_NOC_MAGENTA1); // TopAbs_COMPSOLID
941 myMapSelectionModeColors.Bind ( 8, Quantity_NOC_BROWN); // TopAbs_COMPOUND
942 myMapSelectionModeColors.Bind (0x0010, Quantity_NOC_PINK); // MeshVS_SMF_Volume
943 myMapSelectionModeColors.Bind (0x001E, Quantity_NOC_LIMEGREEN); // MeshVS_SMF_Element
944 myMapSelectionModeColors.Bind (0x001F, Quantity_NOC_DARKOLIVEGREEN); // MeshVS_SMF_All
945 myMapSelectionModeColors.Bind (0x0100, Quantity_NOC_GOLD); // MeshVS_SMF_Group
946 }
947
948 virtual void Fill (const Standard_Integer theCol,
949 const Standard_Integer theRow,
950 const Standard_Integer thePicked) Standard_OVERRIDE
951 {
952 if (thePicked < 1
953 || thePicked > myMainSel->NbPicked())
954 {
955 myImage->SetPixelColor (theCol, theRow, Quantity_Color (Quantity_NOC_BLACK));
956 return;
957 }
958
959 Standard_Integer aSelectionMode = -1;
0ef04197 960 const Handle(SelectMgr_SelectableObject)& aSelectable = myMainSel->Picked (thePicked)->Selectable();
961 const Handle(Select3D_SensitiveEntity)& anEntity = myMainSel->PickedEntity (thePicked);
b5cce1ab 962 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (aSelectable->Selections()); aSelIter.More(); aSelIter.Next())
decdee7d 963 {
b5cce1ab 964 const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
965 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
decdee7d 966 {
b5cce1ab 967 if (aSelEntIter.Value()->BaseSensitive() == anEntity)
decdee7d 968 {
969 aSelectionMode = aSelection->Mode();
970 break;
971 }
972 }
973 }
974 if (aSelectionMode == -1)
975 {
976 myImage->SetPixelColor (theCol, theRow, Quantity_Color (Quantity_NOC_BLACK));
977 return;
978 }
979
980 if (!myMapSelectionModeColors.IsBound (aSelectionMode))
981 {
982 Quantity_Color aColor;
983 randomPastelColor (aColor);
984 myMapSelectionModeColors.Bind (aSelectionMode, aColor);
985 }
986
987 const Quantity_Color& aColor = myMapSelectionModeColors.Find (aSelectionMode);
988 myImage->SetPixelColor (theCol, theRow, aColor);
989 }
990
991 protected:
992 NCollection_DataMap<Standard_Integer, Quantity_Color> myMapSelectionModeColors;
993 };
994
995 //! Help class for filling pixel with color of detected shape.
996 class DetectedObjectColorFiller : public BaseFiller
997 {
998 DEFINE_STANDARD_RTTI_INLINE(DetectedObjectColorFiller, BaseFiller)
999 public:
1000 DetectedObjectColorFiller (Image_PixMap& thePixMap,
1001 StdSelect_ViewerSelector3d* theSelector)
1002 : BaseFiller (thePixMap, theSelector) {}
1003
1004 virtual void Fill (const Standard_Integer theCol,
1005 const Standard_Integer theRow,
1006 const Standard_Integer thePicked) Standard_OVERRIDE
1007 {
1008 Quantity_Color aColor (Quantity_NOC_BLACK);
1009 if (thePicked > 0
1010 && thePicked <= myMainSel->NbPicked())
1011 {
1012 const Handle(SelectMgr_SelectableObject)& aSelectable = myMainSel->Picked (thePicked)->Selectable();
1013 aColor = aSelectable->Attributes()->Color();
1014 }
1015 myImage->SetPixelColor (theCol, theRow, aColor);
1016 }
1017 };
1018
1019}
1020
1021//=======================================================================
1022//function : ToPixMap
1023//purpose :
1024//=======================================================================
1025Standard_Boolean StdSelect_ViewerSelector3d::ToPixMap (Image_PixMap& theImage,
1026 const Handle(V3d_View)& theView,
1027 const StdSelect_TypeOfSelectionImage theType,
1028 const Standard_Integer thePickedIndex)
1029{
1030 if (theImage.IsEmpty())
1031 {
9775fa61 1032 throw Standard_ProgramError("StdSelect_ViewerSelector3d::ToPixMap() has been called with empty image");
decdee7d 1033 }
1034
1035 Handle(BaseFiller) aFiller;
1036 switch (theType)
1037 {
1038 case StdSelect_TypeOfSelectionImage_NormalizedDepth:
1039 case StdSelect_TypeOfSelectionImage_NormalizedDepthInverted:
1040 {
1041 aFiller = new NormalizedDepthFiller (theImage, this,
1042 theType == StdSelect_TypeOfSelectionImage_NormalizedDepthInverted);
1043 break;
1044 }
1045 case StdSelect_TypeOfSelectionImage_UnnormalizedDepth:
1046 {
1047 aFiller = new UnnormalizedDepthFiller (theImage, this);
1048 break;
1049 }
1050 case StdSelect_TypeOfSelectionImage_ColoredDetectedObject:
1051 {
1052 aFiller = new DetectedObjectColorFiller (theImage, this);
1053 break;
1054 }
1055 case StdSelect_TypeOfSelectionImage_ColoredEntity:
1056 {
1057 aFiller = new GeneratedEntityColorFiller (theImage, this, mySelectableObjects);
1058 break;
1059 }
1060 case StdSelect_TypeOfSelectionImage_ColoredOwner:
1061 {
1062 aFiller = new GeneratedOwnerColorFiller (theImage, this, mySelectableObjects);
1063 break;
1064 }
1065 case StdSelect_TypeOfSelectionImage_ColoredSelectionMode:
1066 {
1067 aFiller = new GeneratedSelModeColorFiller (theImage, this);
1068 break;
1069 }
1070 }
1071 if (aFiller.IsNull())
1072 {
1073 return Standard_False;
1074 }
1075
1076 const Standard_Integer aSizeX = static_cast<Standard_Integer> (theImage.SizeX());
1077 const Standard_Integer aSizeY = static_cast<Standard_Integer> (theImage.SizeY());
1078 for (Standard_Integer aRowIter = 0; aRowIter < aSizeY; ++aRowIter)
1079 {
1080 for (Standard_Integer aColIter = 0; aColIter < aSizeX; ++aColIter)
1081 {
1082 Pick (aColIter, aRowIter, theView);
1083 aFiller->Fill (aColIter, aRowIter, thePickedIndex);
1084 }
1085 }
1086 aFiller->Flush();
1087 return Standard_True;
1088}