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