0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Select3D / Select3D_InteriorSensitivePointSet.cxx
CommitLineData
f751596e 1// Created on: 2014-08-15
2// Created by: Varvara POSKONINA
3// Copyright (c) 2005-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
f751596e 16#include <gp_XYZ.hxx>
17
f751596e 18#include <Select3D_InteriorSensitivePointSet.hxx>
19
92efcf78 20IMPLEMENT_STANDARD_RTTIEXT(Select3D_InteriorSensitivePointSet,Select3D_SensitiveSet)
21
bf3977c9 22namespace {
23
f751596e 24// Internal class for creation of planar polygons
25class Select3D_Plane
26{
27public:
28
29 Select3D_Plane()
30 : myPlane (0.0),
31 myIsInitialized (Standard_False)
32 {}
33
34 Standard_Boolean Contains (const gp_Pnt& thePnt) const
35 {
36 if (!myIsInitialized)
37 return Standard_False;
38
39 Standard_Real aRes = myPlane.x() * thePnt.X() +
40 myPlane.y() * thePnt.Y() +
41 myPlane.z() * thePnt.Z() +
42 myPlane.w();
43
44 if (aRes < Precision::Confusion())
45 return Standard_True;
46
47 return Standard_False;
48 }
49
50 void MakePlane (const gp_Pnt& thePnt1,
51 const gp_Pnt& thePnt2,
52 const gp_Pnt& thePnt3)
53 {
54 const gp_XYZ& aVec1 = thePnt2.XYZ() - thePnt1.XYZ();
55 const gp_XYZ& aVec2 = thePnt3.XYZ() - thePnt1.XYZ();
56 const gp_XYZ& aDir = aVec1.Crossed (aVec2);
57 Standard_Real aD = aDir.Dot (thePnt1.XYZ().Reversed());
58 myPlane = NCollection_Vec4<Standard_Real> (aDir.X(), aDir.Y(), aDir.Z(), aD);
59 myIsInitialized = Standard_True;
60 }
61
62 void Invalidate()
63 {
64 myIsInitialized = Standard_False;
65 }
66
67 Standard_Boolean IsValid() const
68 {
69 return myIsInitialized;
70 }
71
72private:
73 NCollection_Vec4<Standard_Real> myPlane;
74 Standard_Boolean myIsInitialized;
75};
76
bf3977c9 77} // anonymous namespace
78
bf3977c9 79
f751596e 80// =======================================================================
81// function : Select3D_InteriorSensitivePointSet
82// purpose : Splits the given point set thePoints onto planar convex
83// polygons
84// =======================================================================
0ef04197 85Select3D_InteriorSensitivePointSet::Select3D_InteriorSensitivePointSet (const Handle(SelectMgr_EntityOwner)& theOwnerId,
f751596e 86 const TColgp_Array1OfPnt& thePoints)
87 : Select3D_SensitiveSet (theOwnerId)
88{
89 Select3D_Plane aPlane;
f751596e 90 Standard_Integer aLowerIdx = thePoints.Lower();
91 Standard_Integer anUpperIdx = thePoints.Upper();
f751596e 92 Standard_Integer aStartIdx = aLowerIdx, anEndIdx = 0;
93 Select3D_BndBox3d aBndBox;
94 gp_XYZ aPntSum (0.0, 0.0, 0.0);
95 for (Standard_Integer aPntIter = aLowerIdx; aPntIter <= anUpperIdx; ++aPntIter)
96 {
97 gp_Pnt aPnt1, aPnt2;
1c22cc2d 98 const gp_Pnt& aPnt3 = thePoints.Value (aPntIter);
f751596e 99 aPntSum += aPnt3.XYZ();
100 SelectMgr_Vec3 aCurrPnt (aPnt3.X(), aPnt3.Y(), aPnt3.Z());
101 aBndBox.Add (aCurrPnt);
102 if (aPntIter - aLowerIdx >= 2)
103 {
1c22cc2d 104 aPnt1 = thePoints.Value (aPntIter - 2);
105 aPnt2 = thePoints.Value (aPntIter - 1);
f751596e 106 }
107 if (aPntIter - aStartIdx == 2 && !aPlane.IsValid())
108 {
109 aPlane.MakePlane (aPnt1, aPnt2, aPnt3);
110 aStartIdx = aPntIter - 2;
111 anEndIdx = aPntIter;
1c22cc2d 112
113 if (anEndIdx == anUpperIdx)
114 {
115 Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anEndIdx - aStartIdx);
116 for (Standard_Integer aIdx = aStartIdx; aIdx <= anEndIdx; ++aIdx)
117 {
118 aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value(aIdx));
119 }
120 Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
121 aPointsArray,
122 Standard_False);
123 myPlanarPolygons.Append (aPlanarPolyg);
124 }
f751596e 125 }
126 else if (aPlane.IsValid())
127 {
128 const gp_XYZ& aVec1 = aPnt1.XYZ() - aPnt2.XYZ();
129 const gp_XYZ& aVec2 = aPnt3.XYZ() - aPnt2.XYZ();
130 Standard_Real anAngle = aVec1.Dot (aVec2);
1c22cc2d 131 if (!aPlane.Contains (thePoints.Value (aPntIter)) || anAngle > Precision::Confusion())
f751596e 132 {
7bb2b829 133 // subtract 1 due to indexation from zero in sub-polygons
134 Standard_Integer anUpperBound = aPntIter - aStartIdx - 1;
f751596e 135 Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anUpperBound);
136 for (Standard_Integer aIdx = aStartIdx; aIdx <= aStartIdx + anUpperBound; ++aIdx)
137 {
1c22cc2d 138 aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value (aIdx));
f751596e 139 }
140 Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
141 aPointsArray,
2157d6ac 142 Standard_True);
f751596e 143 myPlanarPolygons.Append (aPlanarPolyg);
144 aStartIdx = aPntIter;
145 anEndIdx = aPntIter;
146 aPlane.Invalidate();
147 }
148 else
149 {
150 anEndIdx++;
151 if (anEndIdx == anUpperIdx)
152 {
153 Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anEndIdx - aStartIdx);
154 for (Standard_Integer aIdx = aStartIdx; aIdx <= anEndIdx; ++aIdx)
155 {
1c22cc2d 156 aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value (aIdx));
f751596e 157 }
158 Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
159 aPointsArray,
2157d6ac 160 Standard_True);
f751596e 161 myPlanarPolygons.Append (aPlanarPolyg);
162 }
163 }
164 }
165 }
166
1c22cc2d 167 myCOG = aPntSum / thePoints.Length();
168 myBndBox = aBndBox;
169
f751596e 170 myPolygonsIdxs = new TColStd_HArray1OfInteger (0, myPlanarPolygons.Length() - 1);
171 for (Standard_Integer aIdx = 0; aIdx < myPlanarPolygons.Length(); ++aIdx)
172 {
173 myPolygonsIdxs->SetValue (aIdx, aIdx);
174 }
f751596e 175}
176
f751596e 177// =======================================================================
178// function : GetPoints
179// purpose : Initializes the given array theHArrayOfPnt by 3d
180// coordinates of vertices of the whole point set
181// =======================================================================
182void Select3D_InteriorSensitivePointSet::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
183{
184 Standard_Integer aSize = 0;
185 for (Standard_Integer anIdx = 0; anIdx < myPlanarPolygons.Length(); ++anIdx)
186 {
187 const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (anIdx);
188 aSize += aPolygon->NbSubElements();
189 }
f751596e 190
191 theHArrayOfPnt = new TColgp_HArray1OfPnt (1, aSize);
192 Standard_Integer anOutputPntArrayIdx = 1;
193
194 for (Standard_Integer aPolygIdx = 0; aPolygIdx < myPlanarPolygons.Length(); ++aPolygIdx)
195 {
196 const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx);
197 Handle(TColgp_HArray1OfPnt) aPoints;
198 aPolygon->Points3D (aPoints);
199 Standard_Integer anUpper = aPolygIdx < myPlanarPolygons.Length() - 1 ? aPoints->Upper() : aPoints->Upper() + 1;
200 for (Standard_Integer aPntIter = 1; aPntIter < anUpper; ++aPntIter)
201 {
202 theHArrayOfPnt->SetValue (anOutputPntArrayIdx, aPoints->Value (aPntIter));
203 anOutputPntArrayIdx++;
204 }
205 aPoints.Nullify();
206 }
207}
208
209//=======================================================================
210// function : Size
211// purpose : Returns the length of vector of planar convex polygons
212//=======================================================================
213Standard_Integer Select3D_InteriorSensitivePointSet::Size() const
214{
215 return myPlanarPolygons.Length();
216}
217
218//=======================================================================
219// function : Box
220// purpose : Returns bounding box of planar convex polygon with index
221// theIdx
222//=======================================================================
223Select3D_BndBox3d Select3D_InteriorSensitivePointSet::Box (const Standard_Integer theIdx) const
224{
225 Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theIdx);
226 return myPlanarPolygons.Value (aPolygIdx)->BoundingBox();
227}
228
229//=======================================================================
230// function : Center
231// purpose : Returns geometry center of planar convex polygon with index
232// theIdx in the vector along the given axis theAxis
233//=======================================================================
234Standard_Real Select3D_InteriorSensitivePointSet::Center (const Standard_Integer theIdx,
235 const Standard_Integer theAxis) const
236{
39b7b2a4 237 const Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theIdx);
238 const gp_Pnt aCOG = myPlanarPolygons.Value (aPolygIdx)->CenterOfGeometry();
239 return aCOG.Coord (theAxis - 1);
f751596e 240}
241
242//=======================================================================
243// function : Swap
244// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector
245//=======================================================================
246void Select3D_InteriorSensitivePointSet::Swap (const Standard_Integer theIdx1,
247 const Standard_Integer theIdx2)
248{
249 Standard_Integer aPolygIdx1 = myPolygonsIdxs->Value (theIdx1);
250 Standard_Integer aPolygIdx2 = myPolygonsIdxs->Value (theIdx2);
251
252 myPolygonsIdxs->ChangeValue (theIdx1) = aPolygIdx2;
253 myPolygonsIdxs->ChangeValue (theIdx2) = aPolygIdx1;
254}
255
256// =======================================================================
257// function : overlapsElement
4a056d20 258// purpose :
f751596e 259// =======================================================================
4a056d20 260Standard_Boolean Select3D_InteriorSensitivePointSet::overlapsElement (SelectBasics_PickResult& thePickResult,
261 SelectBasics_SelectingVolumeManager& theMgr,
f751596e 262 Standard_Integer theElemIdx,
4a056d20 263 Standard_Boolean )
f751596e 264{
265 Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theElemIdx);
266 const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx);
267 Handle(TColgp_HArray1OfPnt) aPoints;
268 aPolygon->Points3D (aPoints);
6a920e02 269 return theMgr.OverlapsPolygon (aPoints->Array1(), Select3D_TOS_INTERIOR, thePickResult);
f751596e 270}
271
2157d6ac 272// =======================================================================
273// function : elementIsInside
274// purpose :
275// =======================================================================
276Standard_Boolean Select3D_InteriorSensitivePointSet::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
4a056d20 277 Standard_Integer theElemIdx,
278 Standard_Boolean theIsFullInside)
2157d6ac 279{
17017555 280 SelectBasics_PickResult aDummy;
4a056d20 281 return overlapsElement (aDummy, theMgr, theElemIdx, theIsFullInside);
2157d6ac 282}
283
f751596e 284// =======================================================================
285// function : distanceToCOG
286// purpose : Calculates distance from the 3d projection of used-picked
287// screen point to center of the geometry
288// =======================================================================
289Standard_Real Select3D_InteriorSensitivePointSet::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
290{
291 return theMgr.DistToGeometryCenter (myCOG);
292}
293
294//=======================================================================
295// function : BoundingBox
296// purpose : Returns bounding box of the point set. If location
297// transformation is set, it will be applied
298//=======================================================================
299Select3D_BndBox3d Select3D_InteriorSensitivePointSet::BoundingBox()
300{
301 return myBndBox;
302}
303
304//=======================================================================
305// function : CenterOfGeometry
306// purpose : Returns center of the point set. If location transformation
307// is set, it will be applied
308//=======================================================================
309gp_Pnt Select3D_InteriorSensitivePointSet::CenterOfGeometry() const
310{
311 return myCOG;
312}
313
f751596e 314//=======================================================================
315// function : NbSubElements
316// purpose : Returns the amount of points in set
317//=======================================================================
fe758dbe 318Standard_Integer Select3D_InteriorSensitivePointSet::NbSubElements() const
f751596e 319{
320 return myPlanarPolygons.Length();
321}
bc73b006 322
323// =======================================================================
324// function : DumpJson
325// purpose :
326// =======================================================================
327void Select3D_InteriorSensitivePointSet::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
328{
329 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
330 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Select3D_SensitiveSet)
331
332 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBndBox)
333}