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