1
1
#pragma once
2
2
3
+ #include < map>
4
+
5
+ #include " ifcpp/Model/OpenMPIncludes.h"
6
+
3
7
#include " ifcpp/Geometry/CAdapter.h"
4
8
#include " ifcpp/Geometry/GeomUtils.h"
5
9
#include " ifcpp/Geometry/Matrix.h"
@@ -49,6 +53,11 @@ class CurveConverter {
49
53
std::shared_ptr<SplineConverter<TVector>> m_splineConverter;
50
54
std::shared_ptr<Parameters> m_parameters;
51
55
56
+ std::map<std::shared_ptr<IfcCurve>, TCurve> m_curveToPointsMap;
57
+ #ifdef ENABLE_OPENMP
58
+ Mutex m_curveToPointsMapMutex;
59
+ #endif
60
+
52
61
public:
53
62
CurveConverter ( const std::shared_ptr<PrimitiveTypesConverter<TVector>>& primitivesConverter, const std::shared_ptr<GeomUtils<TVector>>& geomUtils,
54
63
const std::shared_ptr<SplineConverter<TVector>> splineConverter, const std::shared_ptr<Parameters>& parameters )
@@ -58,16 +67,33 @@ class CurveConverter {
58
67
, m_parameters( parameters ) {
59
68
}
60
69
70
+ void ResetCaches () {
71
+ #ifdef ENABLE_OPENMP
72
+ ScopedLock lock ( this ->m_curveToPointsMapMutex );
73
+ #endif
74
+ this ->m_curveToPointsMap = {};
75
+ }
76
+
61
77
TCurve ConvertCurve ( const std::shared_ptr<IfcCurve>& curve ) {
62
78
// ENTITY IfcCurve ABSTRACT SUPERTYPE OF (ONEOF(IfcBoundedCurve, IfcConic, IfcLine, IfcOffsetCurve2D, IfcOffsetCurve3D, IfcPCurve))
63
79
80
+ {
81
+ #ifdef ENABLE_OPENMP
82
+ ScopedLock lock ( this ->m_curveToPointsMapMutex );
83
+ #endif
84
+ if ( this ->m_curveToPointsMap .contains ( curve ) ) {
85
+ return this ->m_curveToPointsMap [ curve ];
86
+ }
87
+ }
88
+
89
+ TCurve result;
90
+
64
91
const auto boundedCurve = dynamic_pointer_cast<IfcBoundedCurve>( curve );
65
92
if ( boundedCurve ) {
66
93
// ENTITY IfcBoundedCurve ABSTRACT SUPERTYPE OF (ONEOF(IfcCompositeCurve, IfcPolyline, IfcTrimmedCurve, IfcBSplineCurve))
67
94
68
95
const auto compositeCurve = dynamic_pointer_cast<IfcCompositeCurve>( boundedCurve );
69
96
if ( compositeCurve ) {
70
- TCurve result;
71
97
for ( const auto & segment: compositeCurve->m_Segments ) {
72
98
TCurve segmentPoints;
73
99
const auto compositeCurveSegment = dynamic_pointer_cast<IfcCompositeCurveSegment>( segment );
@@ -83,12 +109,12 @@ class CurveConverter {
83
109
// TODO: Log error
84
110
}
85
111
}
86
- return this ->m_geomUtils ->SimplifyCurve ( result );
112
+ result = this ->m_geomUtils ->SimplifyCurve ( result );
87
113
}
88
114
89
115
const auto polyLine = dynamic_pointer_cast<IfcPolyline>( curve );
90
116
if ( polyLine ) {
91
- return this ->m_geomUtils ->SimplifyCurve ( this ->m_primitivesConverter ->ConvertPoints ( polyLine->m_Points ) );
117
+ result = this ->m_geomUtils ->SimplifyCurve ( this ->m_primitivesConverter ->ConvertPoints ( polyLine->m_Points ) );
92
118
}
93
119
94
120
const auto trimmedCurve = dynamic_pointer_cast<IfcTrimmedCurve>( boundedCurve );
@@ -111,19 +137,17 @@ class CurveConverter {
111
137
radius1 = radius2 = (float )circle->m_Radius ->m_value ;
112
138
}
113
139
114
- TCurve result;
115
140
int n = this ->m_parameters ->m_numVerticesPerCircle ; // TODO: should be calculated from radius
116
141
n = std::max ( n, this ->m_parameters ->m_minNumVerticesPerArc );
117
142
bool senseAgreement = !trimmedCurve->m_SenseAgreement || trimmedCurve->m_SenseAgreement ->m_value ;
118
- auto [ startAngle, openingAngle ] =
119
- this -> GetTrimmingsForCircle ( trimmedCurve-> m_Trim1 , trimmedCurve-> m_Trim2 , placement.GetTransformed ( AVector::New () ), senseAgreement );
143
+ auto [ startAngle, openingAngle ] = this -> GetTrimmingsForCircle ( trimmedCurve-> m_Trim1 , trimmedCurve-> m_Trim2 ,
144
+ placement.GetTransformed ( AVector::New () ), senseAgreement );
120
145
if ( radius1 > this ->m_parameters ->m_epsilon && radius2 > this ->m_parameters ->m_epsilon ) {
121
146
result = this ->m_geomUtils ->BuildEllipse ( radius1, radius2, startAngle, openingAngle, n );
122
147
} else {
123
148
result.push_back ( AVector::New () );
124
149
}
125
150
placement.TransformLoop ( &result );
126
- return result;
127
151
}
128
152
129
153
const auto line = dynamic_pointer_cast<IfcLine>( trimmedCurve->m_BasisCurve );
@@ -132,7 +156,7 @@ class CurveConverter {
132
156
const auto direction = AVector::Normalized ( this ->m_primitivesConverter ->ConvertVector ( line->m_Dir ) );
133
157
bool senseAgreement = !trimmedCurve->m_SenseAgreement || trimmedCurve->m_SenseAgreement ->m_value ;
134
158
const auto [ l, r ] = this ->GetTrimmingsForLine ( trimmedCurve->m_Trim1 , trimmedCurve->m_Trim2 , origin, direction, senseAgreement );
135
- return {
159
+ result = {
136
160
origin + direction * l,
137
161
origin + direction * r,
138
162
};
@@ -142,13 +166,12 @@ class CurveConverter {
142
166
143
167
const auto bsplineCurve = dynamic_pointer_cast<IfcBSplineCurve>( boundedCurve );
144
168
if ( bsplineCurve ) {
145
- return this ->m_splineConverter ->ConvertBSplineCurve ( bsplineCurve );
169
+ result = this ->m_splineConverter ->ConvertBSplineCurve ( bsplineCurve );
146
170
}
147
171
148
172
const auto indexedPolyCurve = dynamic_pointer_cast<IfcIndexedPolyCurve>( boundedCurve );
149
173
if ( indexedPolyCurve ) {
150
174
std::vector<TVector> points;
151
- TCurve result;
152
175
const auto pointList2d = dynamic_pointer_cast<IfcCartesianPointList2D>( indexedPolyCurve->m_Points );
153
176
if ( pointList2d ) {
154
177
points = this ->m_primitivesConverter ->ConvertPoints ( pointList2d->m_CoordList );
@@ -178,7 +201,6 @@ class CurveConverter {
178
201
}
179
202
}
180
203
}
181
- return result;
182
204
}
183
205
}
184
206
@@ -199,7 +221,6 @@ class CurveConverter {
199
221
radius1 = radius2 = (float )circle->m_Radius ->m_value ;
200
222
}
201
223
202
- TCurve result;
203
224
int n = this ->m_parameters ->m_numVerticesPerCircle ; // TODO: should be calculated from radius
204
225
n = std::max ( n, this ->m_parameters ->m_minNumVerticesPerArc );
205
226
if ( radius1 > this ->m_parameters ->m_epsilon && radius2 > this ->m_parameters ->m_epsilon ) {
@@ -208,14 +229,13 @@ class CurveConverter {
208
229
result.push_back ( AVector::New () );
209
230
}
210
231
placement.TransformLoop ( &result );
211
- return result;
212
232
}
213
233
214
234
const auto line = dynamic_pointer_cast<IfcLine>( curve );
215
235
if ( line && line->m_Pnt && line->m_Dir ) {
216
236
const auto origin = this ->m_primitivesConverter ->ConvertPoint ( line->m_Pnt );
217
237
const auto direction = AVector::Normalized ( this ->m_primitivesConverter ->ConvertVector ( line->m_Dir ) );
218
- return {
238
+ result = {
219
239
origin - direction * this ->m_parameters ->m_modelMaxSize * 0 .5f ,
220
240
origin + direction * this ->m_parameters ->m_modelMaxSize * 0 .5f ,
221
241
};
@@ -224,23 +244,28 @@ class CurveConverter {
224
244
const auto offset_curve_2d = dynamic_pointer_cast<IfcOffsetCurve2D>( curve );
225
245
if ( offset_curve_2d ) {
226
246
// TODO: implement
227
- return {};
247
+ result = {};
228
248
}
229
249
230
250
const auto offset_curve_3d = dynamic_pointer_cast<IfcOffsetCurve3D>( curve );
231
251
if ( offset_curve_3d ) {
232
252
// TODO: implement
233
- return {};
253
+ result = {};
234
254
}
235
255
236
256
const auto pcurve = dynamic_pointer_cast<IfcPcurve>( curve );
237
257
if ( pcurve ) {
238
258
// TODO: implement
239
- return {};
259
+ result = {};
240
260
}
241
261
242
- // TODO: Log error
243
- return {};
262
+ {
263
+ #ifdef ENABLE_OPENMP
264
+ ScopedLock lock ( this ->m_curveToPointsMapMutex );
265
+ #endif
266
+ this ->m_curveToPointsMap [ curve ] = result;
267
+ }
268
+ return result;
244
269
}
245
270
246
271
TCurve TrimCurve ( const TCurve& curve, const TVector& t1, const TVector& t2 ) {
@@ -291,7 +316,7 @@ class CurveConverter {
291
316
return { l, M_PI * 2 - l + r };
292
317
}
293
318
if ( !senseAgreement && l < r ) {
294
- return { l, -l - (M_PI * 2 - r) };
319
+ return { l, -l - ( M_PI * 2 - r ) };
295
320
}
296
321
if ( !senseAgreement && l > r ) {
297
322
return { l, l - r };
0 commit comments