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