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 |
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); |
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 | //======================================================================= |
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 | |
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 | //======================================================================= |
172 | void 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 | //======================================================================= |
192 | void 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 | //======================================================================= |
223 | void 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 |
241 | void 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 |
266 | void 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 | //======================================================================= |
635 | void 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 | |
655 | namespace |
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, |
ba00aab7 |
698 | Quantity_TOC_sRGB); |
decdee7d |
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 | //======================================================================= |
1025 | Standard_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 | } |
bc73b006 |
1089 | |
1090 | //======================================================================= |
1091 | //function : DumpJson |
1092 | //purpose : |
1093 | //======================================================================= |
1094 | void StdSelect_ViewerSelector3d::DumpJson (Standard_OStream& theOStream, Standard_Integer) const |
1095 | { |
1096 | OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream) |
1097 | |
1098 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myStructs.Length()) |
1099 | for (Graphic3d_SequenceOfStructure::Iterator aStructsIt (myStructs); aStructsIt.More(); aStructsIt.Next()) |
1100 | { |
1101 | const Handle(Graphic3d_Structure)& aStructure = aStructsIt.Value(); |
1102 | OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, aStructure) |
1103 | } |
1104 | } |