------------------------------------------------------------------------------------------------
| 295 | |
| 296 | // ------------------------------------------------------------------------------------------------ |
| 297 | void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, |
| 298 | TempMesh& result, |
| 299 | ConversionData& conv) { |
| 300 | const Curve* const curve = Curve::Convert(*solid.Directrix, conv); |
| 301 | if(!curve) { |
| 302 | IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)"); |
| 303 | return; |
| 304 | } |
| 305 | |
| 306 | const unsigned int cnt_segments = conv.settings.cylindricalTessellation; |
| 307 | const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments; |
| 308 | |
| 309 | TempMesh temp; |
| 310 | curve->SampleDiscrete(temp, solid.StartParam, solid.EndParam); |
| 311 | const std::vector<IfcVector3>& curve_points = temp.mVerts; |
| 312 | |
| 313 | const size_t samples = curve_points.size(); |
| 314 | |
| 315 | result.mVerts.reserve(cnt_segments * samples * 4); |
| 316 | result.mVertcnt.reserve((cnt_segments - 1) * samples); |
| 317 | |
| 318 | std::vector<IfcVector3> points; |
| 319 | points.reserve(cnt_segments * samples); |
| 320 | |
| 321 | if(curve_points.empty()) { |
| 322 | IFCImporter::LogWarn("curve evaluation yielded no points (IfcSweptDiskSolid)"); |
| 323 | return; |
| 324 | } |
| 325 | |
| 326 | IfcVector3 current = curve_points[0]; |
| 327 | IfcVector3 previous = current; |
| 328 | IfcVector3 next; |
| 329 | |
| 330 | IfcVector3 startvec; |
| 331 | startvec.x = 1.0f; |
| 332 | startvec.y = 1.0f; |
| 333 | startvec.z = 1.0f; |
| 334 | |
| 335 | unsigned int last_dir = 0; |
| 336 | |
| 337 | // generate circles at the sweep positions |
| 338 | for(size_t i = 0; i < samples; ++i) { |
| 339 | |
| 340 | if(i != samples - 1) { |
| 341 | next = curve_points[i + 1]; |
| 342 | } |
| 343 | |
| 344 | // get a direction vector reflecting the approximate curvature (i.e. tangent) |
| 345 | IfcVector3 d = (current-previous) + (next-previous); |
| 346 | |
| 347 | d.Normalize(); |
| 348 | |
| 349 | // figure out an arbitrary point q so that (p-q) * d = 0, |
| 350 | // try to maximize ||(p-q)|| * ||(p_last-q_last)|| |
| 351 | IfcVector3 q; |
| 352 | bool take_any = false; |
| 353 | |
| 354 | for (unsigned int j = 0; j < 2; ++j, take_any = true) { |