0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / SelectMgr / SelectMgr.cxx
CommitLineData
7f24b768 1// Copyright (c) 2020 OPEN CASCADE SAS
2//
3// This file is part of Open CASCADE Technology software library.
4//
5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
10//
11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
13
14#include <SelectMgr.hxx>
15
16#include <Graphic3d_ArrayOfPoints.hxx>
17#include <Graphic3d_AspectMarker3d.hxx>
18#include <Graphic3d_Group.hxx>
19#include <Graphic3d_Structure.hxx>
20#include <Poly_Array1OfTriangle.hxx>
21#include <Poly_Triangulation.hxx>
22#include <Prs3d.hxx>
23#include <Prs3d_LineAspect.hxx>
24#include <Prs3d_NListOfSequenceOfPnt.hxx>
25#include <TColgp_HArray1OfPnt.hxx>
26#include <TColgp_SequenceOfPnt.hxx>
27#include <Select3D_SensitiveBox.hxx>
28#include <Select3D_SensitiveEntity.hxx>
29#include <Select3D_SensitiveFace.hxx>
30#include <Select3D_SensitivePoint.hxx>
31#include <Select3D_SensitiveSegment.hxx>
32#include <Select3D_SensitiveTriangle.hxx>
33#include <Select3D_SensitiveTriangulation.hxx>
34#include <Select3D_SensitiveWire.hxx>
35#include <SelectMgr_Selection.hxx>
36
37namespace
38{
39 //! Compute polyline of shrunk triangle.
40 static Handle(TColgp_HSequenceOfPnt) shrunkTriangle (const gp_Pnt* thePnts,
41 const gp_XYZ& theCenter)
42 {
43 const gp_XYZ aV1 = theCenter + (thePnts[0].XYZ() - theCenter) * 0.9;
44 const gp_XYZ aV2 = theCenter + (thePnts[1].XYZ() - theCenter) * 0.9;
45 const gp_XYZ aV3 = theCenter + (thePnts[2].XYZ() - theCenter) * 0.9;
46 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
47 aPoints->Append (aV1);
48 aPoints->Append (aV2);
49 aPoints->Append (aV3);
50 aPoints->Append (aV1);
51 return aPoints;
52 }
53
54 //! Fill in triangulation polylines.
55 static void addTriangulation (Prs3d_NListOfSequenceOfPnt& theSeqLines,
56 Prs3d_NListOfSequenceOfPnt& theSeqFree,
57 const Handle(Select3D_SensitiveTriangulation)& theTri,
58 const gp_Trsf& theLoc)
59 {
60 gp_Trsf aTrsf = theLoc;
61 if (theTri->HasInitLocation())
62 {
63 aTrsf = theLoc * theTri->GetInitLocation();
64 }
65 const Handle(Poly_Triangulation)& aPolyTri = theTri->Triangulation();
66 for (Standard_Integer aTriIter = 1; aTriIter <= aPolyTri->NbTriangles(); ++aTriIter)
67 {
68 const Poly_Triangle& aTri = aPolyTri->Triangle (aTriIter);
69 const gp_Pnt aPnts[3] =
70 {
71 aPolyTri->Node (aTri (1)).Transformed (aTrsf),
72 aPolyTri->Node (aTri (2)).Transformed (aTrsf),
73 aPolyTri->Node (aTri (3)).Transformed (aTrsf)
74 };
75 const gp_XYZ aCenter = (aPnts[0].XYZ() + aPnts[1].XYZ() + aPnts[2].XYZ()) / 3.0;
76 theSeqLines.Append (shrunkTriangle (aPnts, aCenter));
77 }
78
79 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
80 Prs3d::AddFreeEdges (*aPoints, aPolyTri, aTrsf);
81 if (!aPoints->IsEmpty())
82 {
83 theSeqFree.Append (aPoints);
84 }
85 }
86
87 //! Fill in bounding box polylines.
88 static void addBoundingBox (Prs3d_NListOfSequenceOfPnt& theSeqLines,
89 const Handle(Select3D_SensitiveBox)& theSensBox,
90 const gp_Trsf& theLoc)
91 {
92 Graphic3d_Vec3d aMin, aMax;
93 theSensBox->Box().Get (aMin.x(), aMin.y(), aMin.z(), aMax.x(), aMax.y(), aMax.z());
94 gp_Pnt aPnts[8] =
95 {
96 gp_Pnt(aMin.x(), aMin.y(), aMin.z()),
97 gp_Pnt(aMax.x(), aMin.y(), aMin.z()),
98 gp_Pnt(aMax.x(), aMax.y(), aMin.z()),
99 gp_Pnt(aMin.x(), aMax.y(), aMin.z()),
100 gp_Pnt(aMin.x(), aMin.y(), aMax.z()),
101 gp_Pnt(aMax.x(), aMin.y(), aMax.z()),
102 gp_Pnt(aMax.x(), aMax.y(), aMax.z()),
103 gp_Pnt(aMin.x(), aMax.y(), aMax.z())
104 };
105 for (Standard_Integer aPntIter = 0; aPntIter <= 7; ++aPntIter)
106 {
107 aPnts[aPntIter].Transform (theLoc);
108 }
109
110 {
111 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
112 for (Standard_Integer i = 0; i < 4; ++i)
113 {
114 aPoints->Append (aPnts[i]);
115 }
116 aPoints->Append (aPnts[0]);
117 theSeqLines.Append (aPoints);
118 }
119 {
120 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
121 for (Standard_Integer i = 4; i < 8; i++)
122 {
123 aPoints->Append (aPnts[i]);
124 }
125 aPoints->Append (aPnts[4]);
126 theSeqLines.Append (aPoints);
127 }
128 for (Standard_Integer i = 0; i < 4; i++)
129 {
130 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
131 aPoints->Append (aPnts[i]);
132 aPoints->Append (aPnts[i+4]);
133 theSeqLines.Append (aPoints);
134 }
135 }
136}
137
138//=======================================================================
139//function : ComputeSensitivePrs
140//purpose :
141//=======================================================================
142void SelectMgr::ComputeSensitivePrs (const Handle(Graphic3d_Structure)& thePrs,
143 const Handle(SelectMgr_Selection)& theSel,
144 const gp_Trsf& theLoc,
145 const Handle(Graphic3d_TransformPers)& theTrsfPers)
146{
147 thePrs->SetTransformPersistence (theTrsfPers);
148
149 Prs3d_NListOfSequenceOfPnt aSeqLines, aSeqFree;
150 TColgp_SequenceOfPnt aSeqPoints;
151 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
152 {
153 const Handle(Select3D_SensitiveEntity)& anEnt = aSelEntIter.Value()->BaseSensitive();
154 if (Handle(Select3D_SensitiveBox) aSensBox = Handle(Select3D_SensitiveBox)::DownCast (anEnt))
155 {
156 addBoundingBox (aSeqLines, aSensBox, theLoc);
157 }
158 else if (Handle(Select3D_SensitiveFace) aFace = Handle(Select3D_SensitiveFace)::DownCast(anEnt))
159 {
160 Handle(TColgp_HArray1OfPnt) aSensPnts;
161 aFace->GetPoints (aSensPnts);
162 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
163 for (TColgp_HArray1OfPnt::Iterator aPntIter (*aSensPnts); aPntIter.More(); aPntIter.Next())
164 {
165 aPoints->Append (aPntIter.Value().Transformed (theLoc));
166 }
167 aSeqLines.Append (aPoints);
168 }
169 else if (Handle(Select3D_SensitivePoly) aSensPoly = Handle(Select3D_SensitivePoly)::DownCast (anEnt))
170 {
171 Standard_Integer aFrom = 0, aTo = 0;
172 aSensPoly->ArrayBounds (aFrom, aTo);
173 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
174 for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; ++aPntIter)
175 {
176 aPoints->Append (aSensPoly->GetPoint3d (aPntIter).Transformed (theLoc));
177 }
178 aSeqLines.Append (aPoints);
179 }
180 else if (Handle(Select3D_SensitiveWire) aWire = Handle(Select3D_SensitiveWire)::DownCast(anEnt))
181 {
182 const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& anEntities = aWire->GetEdges();
183 for (NCollection_Vector<Handle(Select3D_SensitiveEntity)>::Iterator aSubIter (anEntities); aSubIter.More(); aSubIter.Next())
184 {
185 const Handle(Select3D_SensitiveEntity)& aSubEnt = aSubIter.Value();
186 if (Handle(Select3D_SensitiveSegment) aSensSeg = Handle(Select3D_SensitiveSegment)::DownCast (aSubEnt))
187 {
188 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
189 aPoints->Append (aSensSeg->StartPoint().Transformed (theLoc));
190 aPoints->Append (aSensSeg->EndPoint() .Transformed (theLoc));
191 aSeqLines.Append (aPoints);
192 }
193 else if (Handle(Select3D_SensitivePoly) aSubSensPoly = Handle(Select3D_SensitivePoly)::DownCast (aSubEnt))
194 {
195 Standard_Integer aFrom = 0, aTo = 0;
196 aSubSensPoly->ArrayBounds (aFrom, aTo);
197 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
198 for (Standard_Integer aPntIter = aFrom; aPntIter <= aTo; ++aPntIter)
199 {
200 aPoints->Append (aSubSensPoly->GetPoint3d (aPntIter).Transformed (theLoc));
201 }
202 aSeqLines.Append (aPoints);
203 }
204 }
205 }
206 else if (Handle(Select3D_SensitiveSegment) aSensSeg = Handle(Select3D_SensitiveSegment)::DownCast(anEnt))
207 {
208 Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt();
209 aPoints->Append (aSensSeg->StartPoint().Transformed (theLoc));
210 aPoints->Append (aSensSeg->EndPoint() .Transformed (theLoc));
211 aSeqLines.Append (aPoints);
212 }
213 else if (Handle(Select3D_SensitivePoint) aSensPnt = Handle(Select3D_SensitivePoint)::DownCast(anEnt))
214 {
215 aSeqPoints.Append (aSensPnt->Point().Transformed (theLoc));
216 }
217 else if (Handle(Select3D_SensitiveTriangulation) aSensTri = Handle(Select3D_SensitiveTriangulation)::DownCast (anEnt))
218 {
219 addTriangulation (aSeqLines, aSeqFree, aSensTri, theLoc);
220 }
221 else if (Handle(Select3D_SensitiveTriangle) aSensTri1 = Handle(Select3D_SensitiveTriangle)::DownCast(anEnt))
222 {
223 gp_Pnt aPnts[3];
224 aSensTri1->Points3D (aPnts[0], aPnts[1], aPnts[2]);
225 aPnts[0].Transform (theLoc);
226 aPnts[1].Transform (theLoc);
227 aPnts[2].Transform (theLoc);
228 aSeqLines.Append (shrunkTriangle (aPnts, aSensTri1->Center3D().XYZ()));
229 }
230 }
231
232 if (!aSeqPoints.IsEmpty())
233 {
234 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (aSeqPoints.Size());
235 for (TColgp_SequenceOfPnt::Iterator aPntIter (aSeqPoints); aPntIter.More(); aPntIter.Next())
236 {
237 anArrayOfPoints->AddVertex (aPntIter.Value());
238 }
239
240 Handle(Graphic3d_Group) aSensPntGroup = thePrs->NewGroup();
241 aSensPntGroup->SetPrimitivesAspect (new Graphic3d_AspectMarker3d (Aspect_TOM_O_PLUS, Quantity_NOC_INDIANRED3, 2.0));
242 aSensPntGroup->AddPrimitiveArray (anArrayOfPoints);
243 }
244 if (!aSeqLines.IsEmpty())
245 {
246 Prs3d::AddPrimitivesGroup (thePrs, new Prs3d_LineAspect (Quantity_NOC_AQUAMARINE1, Aspect_TOL_DASH, 1.0), aSeqLines);
247 }
248 if (!aSeqFree.IsEmpty())
249 {
250 Prs3d::AddPrimitivesGroup (thePrs, new Prs3d_LineAspect (Quantity_NOC_GREEN, Aspect_TOL_SOLID, 2.0), aSeqFree);
251 }
252}