0029528: Visualization, TKOpenGl - allow defining sRGB textures
[occt.git] / src / StdSelect / StdSelect_ViewerSelector3d.cxx
1 // Created on: 1995-03-15
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <StdSelect_ViewerSelector3d.hxx>
18 #include <StdSelect.hxx>
19 #include <Select3D_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>
27 #include <gp_Pln.hxx>
28 #include <Select3D_SensitiveEntity.hxx>
29 #include <Graphic3d_ArrayOfPolylines.hxx>
30 #include <Graphic3d_Group.hxx>
31 #include <Graphic3d_SequenceOfHClipPlane.hxx>
32 #include <Graphic3d_Structure.hxx>
33 #include <SelectMgr_SelectableObject.hxx>
34 #include <TColgp_HArray1OfPnt.hxx>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <TColgp_Array1OfPnt2d.hxx>
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>
46 #include <Select3D_SensitiveBox.hxx>
47 #include <SelectMgr_Selection.hxx>
48 #include <SelectMgr_EntityOwner.hxx>
49
50 #include <Aspect_Grid.hxx>
51 #include <Aspect_TypeOfMarker.hxx>
52 #include <Aspect_Window.hxx>
53 #include <Graphic3d_AspectMarker3d.hxx>
54 #include <Graphic3d_ArrayOfPoints.hxx>
55 #include <math_BullardGenerator.hxx>
56 #include <Message.hxx>
57 #include <Message_Messenger.hxx>
58 #include <Quantity_ColorHasher.hxx>
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>
67 #include <V3d_Viewer.hxx>
68 #include <TColgp_SequenceOfPnt.hxx>
69
70 #include <OSD_Timer.hxx>
71
72
73 IMPLEMENT_STANDARD_RTTIEXT(StdSelect_ViewerSelector3d,SelectMgr_ViewerSelector)
74
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
90 //=======================================================================
91 // Function : Constructor
92 // Purpose  :
93 //=======================================================================
94 StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() {}
95
96 //=======================================================================
97 // Function: SetPixelTolerance
98 // Purpose :
99 //=======================================================================
100 void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance)
101 {
102   if (myTolerances.Tolerance() != theTolerance)
103   {
104     if (theTolerance < 0)
105       myTolerances.ResetDefaults();
106     else
107       myTolerances.SetCustomTolerance (theTolerance);
108     myToUpdateTolerance = Standard_True;
109   }
110 }
111
112 //=======================================================================
113 // Function: Pick
114 // Purpose :
115 //=======================================================================
116 void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
117                                        const Standard_Integer theYPix,
118                                        const Handle(V3d_View)& theView)
119 {
120   updateZLayers (theView);
121   if(myToUpdateTolerance)
122   {
123     mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
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);
135   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
136
137   TraverseSensitives();
138 }
139
140 //=======================================================================
141 // Function: Pick
142 // Purpose :
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)
149 {
150   updateZLayers (theView);
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   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
164
165   TraverseSensitives();
166 }
167
168 //=======================================================================
169 // Function: Pick
170 // Purpose : Selection using a polyline
171 //=======================================================================
172 void StdSelect_ViewerSelector3d::Pick (const TColgp_Array1OfPnt2d& thePolyline,
173                                        const Handle(V3d_View)& theView)
174 {
175   updateZLayers (theView);
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
183   mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes(), Handle(Graphic3d_SequenceOfHClipPlane)());
184
185   TraverseSensitives();
186 }
187
188 //=======================================================================
189 // Function: DisplaySensitive.
190 // Purpose : Display active primitives.
191 //=======================================================================
192 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(V3d_View)& theView)
193 {
194   for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
195   {
196     Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
197     const Handle (SelectMgr_SelectableObject)& anObj = aSelectableIt.Value();
198     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
199     {
200       if (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated)
201       {
202         computeSensitivePrs (aStruct, aSelIter.Value(), anObj->Transformation(), Handle(Graphic3d_TransformPers)());
203       }
204     }
205
206     myStructs.Append (aStruct);
207   }
208
209   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
210   {
211     Handle(Graphic3d_Structure)& aStruct = aStructIter.ChangeValue();
212     aStruct->SetDisplayPriority (10);
213     aStruct->Display();
214   }
215
216   theView->Update();
217 }
218
219 //=======================================================================
220 // Function: ClearSensitive
221 // Purpose :
222 //=======================================================================
223 void StdSelect_ViewerSelector3d::ClearSensitive (const Handle(V3d_View)& theView)
224 {
225   for (Graphic3d_SequenceOfStructure::Iterator aStructIter (myStructs); aStructIter.More(); aStructIter.Next())
226   {
227     aStructIter.ChangeValue()->Remove();
228   }
229   myStructs.Clear();
230
231   if (!theView.IsNull())
232   {
233     theView->Update();
234   }
235 }
236
237 //=======================================================================
238 //function : DisplaySenstive
239 //purpose  :
240 //=======================================================================
241 void StdSelect_ViewerSelector3d::DisplaySensitive (const Handle(SelectMgr_Selection)& theSel,
242                                                    const gp_Trsf& theTrsf,
243                                                    const Handle(V3d_View)& theView,
244                                                    const Standard_Boolean theToClearOthers)
245 {
246   if (theToClearOthers)
247   {
248     ClearSensitive (theView);
249   }
250
251   Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (theView->Viewer()->StructureManager());
252
253   computeSensitivePrs (aStruct, theSel, theTrsf, Handle(Graphic3d_TransformPers)());
254
255   myStructs.Append (aStruct);
256   myStructs.Last()->SetDisplayPriority (10);
257   myStructs.Last()->Display();
258
259   theView->Update();
260 }
261
262 //=======================================================================
263 //function : computeSensitivePrs
264 //purpose  :
265 //=======================================================================
266 void StdSelect_ViewerSelector3d::computeSensitivePrs (const Handle(Graphic3d_Structure)& theStructure,
267                                                       const Handle(SelectMgr_Selection)& theSel,
268                                                       const gp_Trsf& theLoc,
269                                                       const Handle(Graphic3d_TransformPers)& theTrsfPers)
270 {
271   theStructure->SetTransformPersistence (theTrsfPers);
272
273   Handle(Graphic3d_Group) aSensGroup  = theStructure->NewGroup();
274
275   Quantity_Color aColor (Quantity_NOC_INDIANRED3);
276   Handle(Graphic3d_AspectMarker3d) aMarkerAspect =new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, aColor, 2.0);
277
278   aSensGroup->SetPrimitivesAspect (aMarkerAspect);
279   aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
280
281   Handle(Graphic3d_Group) anAreaGroup = theStructure->NewGroup();
282
283   anAreaGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0));
284
285   TColgp_SequenceOfPnt aSeqLines, aSeqFree;
286   TColStd_SequenceOfInteger aSeqBnds;
287   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
288   {
289     const Handle(Select3D_SensitiveEntity)& Ent = aSelEntIter.Value()->BaseSensitive();
290     const Standard_Boolean hasloc = theLoc.Form() != gp_Identity;
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);
301       Standard_Integer i;
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       {
315         for (i = 0; i <= 7; i++)
316           theboxpoint[i].Transform (theLoc);
317       }
318
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]);
328
329       for (i = 0; i < 4; i++)
330       {
331         aSeqBnds.Append(2);
332         aSeqLines.Append(theboxpoint[i]);
333         aSeqLines.Append(theboxpoint[i+4]);
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;
343       aFace->GetPoints(TheHPts);
344       const TColgp_Array1OfPnt& ThePts = TheHPts->Array1();
345
346       aSeqBnds.Append(ThePts.Length());
347       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
348       {
349         if (hasloc)
350           aSeqLines.Append(ThePts(I).Transformed (theLoc));
351         else
352           aSeqLines.Append(ThePts(I));
353       }
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
365       aSeqBnds.Append(ThePts.Length());
366       for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
367       {
368         if (hasloc)
369           aSeqLines.Append(ThePts(I).Transformed (theLoc));
370         else
371           aSeqLines.Append(ThePts(I));
372       }
373     }
374     //==============
375     // Wire
376     //=============
377     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveWire))
378     {
379       Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(Ent);
380       const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& anEntities = aWire->GetEdges();
381
382       for (int i = 0; i < anEntities.Length(); i++)
383       {
384         Handle(Select3D_SensitiveEntity) SubEnt = anEntities.Value(i);
385
386         //Segment
387         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
388         {
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           {
393             P1.Transform(theLoc);
394             P2.Transform(theLoc);
395           }
396           aSeqBnds.Append(2);
397           aSeqLines.Append(P1);
398           aSeqLines.Append(P2);
399         }
400
401         //circle
402         if (SubEnt->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
403         {
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)
409           {
410             gp_Pnt aPnts[3] =
411             {
412               gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
413               gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
414               gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
415             };
416
417             if (hasloc)
418             {
419               aPnts[0].Transform (theLoc);
420               aPnts[1].Transform (theLoc);
421               aPnts[2].Transform (theLoc);
422             }
423
424             aSeqBnds.Append (4);
425             aSeqLines.Append (aPnts[0]);
426             aSeqLines.Append (aPnts[1]);
427             aSeqLines.Append (aPnts[2]);
428             aSeqLines.Append (aPnts[0]);
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();
439
440           aSeqBnds.Append(ThePts.Length());
441           for (Standard_Integer I = ThePts.Lower(); I <= ThePts.Upper(); I++)
442           {
443             if (hasloc)
444               aSeqLines.Append(ThePts(I).Transformed (theLoc));
445             else
446               aSeqLines.Append(ThePts(I));
447           }
448         }
449       }
450     }
451     //==============
452     // Segment
453     //=============
454     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveSegment))
455     {
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       {
460         P1.Transform (theLoc);
461         P2.Transform (theLoc);
462       }
463       aSeqBnds.Append(2);
464       aSeqLines.Append(P1);
465       aSeqLines.Append(P2);
466     }
467     //==============
468     // Circle
469     //=============
470     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveCircle))
471     {
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)
477       {
478         gp_Pnt aPnts[3] =
479         {
480           gp_Pnt (aCircle->GetPoint3d (aPntIter + 0).XYZ()),
481           gp_Pnt (aCircle->GetPoint3d (aPntIter + 1).XYZ()),
482           gp_Pnt (aCircle->GetPoint3d (aPntIter + 2).XYZ())
483         };
484
485         if (hasloc)
486         {
487           aPnts[0].Transform (theLoc);
488           aPnts[1].Transform (theLoc);
489           aPnts[2].Transform (theLoc);
490         }
491
492         aSeqBnds.Append (4);
493         aSeqLines.Append (aPnts[0]);
494         aSeqLines.Append (aPnts[1]);
495         aSeqLines.Append (aPnts[2]);
496         aSeqLines.Append (aPnts[0]);
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() :
506         Handle(Select3D_SensitivePoint)::DownCast(Ent)->Point().Transformed (theLoc);
507       Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
508       anArrayOfPoints->AddVertex (P.X(), P.Y(), P.Z());
509       aSensGroup->AddPrimitiveArray (anArrayOfPoints);
510     }
511     //============================================================
512     // Triangulation : On met un petit offset ves l'interieur...
513     //==========================================================
514     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangulation))
515     {
516       Handle(Poly_Triangulation) PT (Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->Triangulation());
517
518       const Poly_Array1OfTriangle& triangles = PT->Triangles();
519       const TColgp_Array1OfPnt& Nodes = PT->Nodes();
520       Standard_Integer n[3];
521
522       TopLoc_Location iloc, bidloc;
523       if (Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->HasInitLocation())
524         bidloc = Handle(Select3D_SensitiveTriangulation)::DownCast (Ent)->GetInitLocation();
525
526       if (bidloc.IsIdentity())
527         iloc = theLoc;
528       else
529         iloc = theLoc * bidloc;
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;
542         V1 -= CDG; V2 -= CDG; V3 -= CDG;
543         V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
544         V1 += CDG; V2 += CDG; V3 += CDG;
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));
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       }
576       for (Standard_Integer ifri = 1; ifri <= FreeE.Length(); ifri += 2)
577       {
578         gp_Pnt pe1 (Nodes (FreeE (ifri)).Transformed (iloc)), pe2 (Nodes (FreeE (ifri + 1)).Transformed (iloc));
579         aSeqFree.Append(pe1);
580         aSeqFree.Append(pe2);
581       }
582     }
583     else if (Ent->DynamicType()==STANDARD_TYPE(Select3D_SensitiveTriangle))
584     {
585       Handle(Select3D_SensitiveTriangle) Str = Handle(Select3D_SensitiveTriangle)::DownCast(Ent);
586       gp_Pnt P1, P2, P3;
587       Str->Points3D (P1, P2, P3);
588       gp_Pnt CDG = Str->Center3D();
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());
593       V1 *= 0.9; V2 *= 0.9; V3 *= 0.9;
594       V1 += CDG.XYZ(); V2 += CDG.XYZ(); V3 += CDG.XYZ();
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));
601     }
602   }
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));
613     anAreaGroup->AddPrimitiveArray(aPrims);
614   }
615
616   if (aSeqFree.Length())
617   {
618     aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0));
619     Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(aSeqFree.Length(),aSeqFree.Length()/2);
620     for (i = 1; i <= aSeqFree.Length(); i++)
621     {
622       aPrims->AddBound(2);
623       aPrims->AddVertex(aSeqLines(i++));
624       aPrims->AddVertex(aSeqLines(i));
625     }
626     aSensGroup->AddPrimitiveArray(aPrims);
627     aSensGroup->SetPrimitivesAspect (new Graphic3d_AspectLine3d (Quantity_NOC_GRAY40, Aspect_TOL_SOLID, 2.0));
628   }
629 }
630
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());
645     if (aSettings.ToClearDepth()
646      || isPrevDepthWrite != aSettings.ToEnableDepthWrite())
647     {
648       ++aPos;
649     }
650     isPrevDepthWrite = aSettings.ToEnableDepthWrite();
651     myZLayerOrderMap.Bind (aLayerIter.Value(), aPos);
652   }
653 }
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,
698                                  Quantity_TOC_sRGB);
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();
722         for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
723         {
724           const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
725           for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
726           {
727             const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
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
750       const Handle(Select3D_SensitiveEntity)& aPickedEntity = myMainSel->PickedEntity (thePicked);
751       Quantity_Color aColor (Quantity_NOC_BLACK);
752       myMapEntityColors.Find (aPickedEntity, aColor);
753       myImage->SetPixelColor (theCol, theRow, aColor);
754     }
755
756   protected:
757     NCollection_DataMap<Handle(Select3D_SensitiveEntity), Quantity_Color> myMapEntityColors;
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     {
773       myUnnormImage.InitZero (Image_Format_GrayF, thePixMap.SizeX(), thePixMap.SizeY());
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     {
802       float aFrom  = 0.0f;
803       float aDelta = 1.0f;
804       if (myDepthMin <= myDepthMax)
805       {
806         aFrom  = float(myDepthMin);
807         aDelta = float(myDepthMax) - float(myDepthMin);
808         if (aDelta <= ShortRealEpsilon())
809         {
810           aDelta = 1.0f;
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),
822                                     Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
823             continue;
824           }
825
826           float aNormDepth = (aDepth - aFrom) / aDelta;
827           if (myToInverse)
828           {
829             aNormDepth = 1.0f - aNormDepth;
830           }
831           myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
832                                   Quantity_ColorRGBA (aNormDepth, aNormDepth, aNormDepth, 1.0f));
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       {
860         myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
861         return;
862       }
863
864       const SelectMgr_SortCriterion& aSortCriterion = myMainSel->PickedData (thePicked);
865       const float aDepth = float(aSortCriterion.Depth);
866       myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (Graphic3d_Vec4 (aDepth, aDepth, aDepth, 1.0f)));
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();
884         for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
885         {
886           const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
887           for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
888           {
889             const Handle(SelectMgr_SensitiveEntity)& aSens   = aSelEntIter.Value();
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;
960       const Handle(SelectMgr_SelectableObject)& aSelectable = myMainSel->Picked       (thePicked)->Selectable();
961       const Handle(Select3D_SensitiveEntity)&   anEntity    = myMainSel->PickedEntity (thePicked);
962       for (SelectMgr_SequenceOfSelection::Iterator aSelIter (aSelectable->Selections()); aSelIter.More(); aSelIter.Next())
963       {
964         const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
965         for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
966         {
967           if (aSelEntIter.Value()->BaseSensitive() == anEntity)
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   {
1032     throw Standard_ProgramError("StdSelect_ViewerSelector3d::ToPixMap() has been called with empty image");
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 }