|
@@ -581,6 +581,8 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
|
startvec.y = 1.0f;
|
|
startvec.y = 1.0f;
|
|
startvec.z = 1.0f;
|
|
startvec.z = 1.0f;
|
|
|
|
|
|
|
|
+ unsigned int last_dir = 0;
|
|
|
|
+
|
|
// generate circles at the sweep positions
|
|
// generate circles at the sweep positions
|
|
for(size_t i = 0; i < samples; ++i) {
|
|
for(size_t i = 0; i < samples; ++i) {
|
|
|
|
|
|
@@ -596,24 +598,34 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
|
// figure out an arbitrary point q so that (p-q) * d = 0,
|
|
// figure out an arbitrary point q so that (p-q) * d = 0,
|
|
// try to maximize ||(p-q)|| * ||(p_last-q_last)||
|
|
// try to maximize ||(p-q)|| * ||(p_last-q_last)||
|
|
IfcVector3 q;
|
|
IfcVector3 q;
|
|
- if (abs(d.x) > 1e-6) {
|
|
|
|
- q.y = startvec.y;
|
|
|
|
- q.z = startvec.z;
|
|
|
|
- q.x = -(d.y * q.y + d.z * q.z) / d.x;
|
|
|
|
- }
|
|
|
|
- else if (abs(d.y) > 1e-6) {
|
|
|
|
- q.x = startvec.x;
|
|
|
|
- q.z = startvec.z;
|
|
|
|
- q.y = -(d.x * q.x + d.z * q.z) / d.y;
|
|
|
|
- }
|
|
|
|
- else { // if (abs(d.z) > 1e-6)
|
|
|
|
- q.y = startvec.y;
|
|
|
|
- q.x = startvec.x;
|
|
|
|
- q.z = -(d.y * q.y + d.x * q.x) / d.z;
|
|
|
|
|
|
+ bool take_any = false;
|
|
|
|
+
|
|
|
|
+ for (unsigned int i = 0; i < 2; ++i, take_any = true) {
|
|
|
|
+ if ((last_dir == 0 || take_any) && abs(d.x) > 1e-6) {
|
|
|
|
+ q.y = startvec.y;
|
|
|
|
+ q.z = startvec.z;
|
|
|
|
+ q.x = -(d.y * q.y + d.z * q.z) / d.x;
|
|
|
|
+ last_dir = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else if ((last_dir == 1 || take_any) && abs(d.y) > 1e-6) {
|
|
|
|
+ q.x = startvec.x;
|
|
|
|
+ q.z = startvec.z;
|
|
|
|
+ q.y = -(d.x * q.x + d.z * q.z) / d.y;
|
|
|
|
+ last_dir = 1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else if ((last_dir == 2 && abs(d.z) > 1e-6) || take_any) {
|
|
|
|
+ q.y = startvec.y;
|
|
|
|
+ q.x = startvec.x;
|
|
|
|
+ q.z = -(d.y * q.y + d.x * q.x) / d.z;
|
|
|
|
+ last_dir = 2;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- startvec = q;
|
|
|
|
q *= solid.Radius / q.Length();
|
|
q *= solid.Radius / q.Length();
|
|
|
|
+ startvec = q;
|
|
|
|
|
|
// generate a rotation matrix to rotate q around d
|
|
// generate a rotation matrix to rotate q around d
|
|
IfcMatrix4 rot;
|
|
IfcMatrix4 rot;
|
|
@@ -630,12 +642,27 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
|
// make quads
|
|
// make quads
|
|
for(size_t i = 0; i < samples - 1; ++i) {
|
|
for(size_t i = 0; i < samples - 1; ++i) {
|
|
|
|
|
|
- for (unsigned int seg = 0; seg < cnt_segments - 1; ++seg) {
|
|
|
|
|
|
+ const aiVector3D& this_start = points[ i * cnt_segments ];
|
|
|
|
+
|
|
|
|
+ // locate corresponding point on next sample ring
|
|
|
|
+ unsigned int best_pair_offset = 0;
|
|
|
|
+ float best_distance_squared = 1e10f;
|
|
|
|
+ for (unsigned int seg = 0; seg < cnt_segments; ++seg) {
|
|
|
|
+ const aiVector3D& p = points[ (i+1) * cnt_segments + seg];
|
|
|
|
+ const float l = (p-this_start).SquareLength();
|
|
|
|
+
|
|
|
|
+ if(l < best_distance_squared) {
|
|
|
|
+ best_pair_offset = seg;
|
|
|
|
+ best_distance_squared = l;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (unsigned int seg = 0; seg < cnt_segments; ++seg) {
|
|
|
|
|
|
- result.verts.push_back(points[ i * cnt_segments + seg]);
|
|
|
|
- result.verts.push_back(points[ i * cnt_segments + seg + 1]);
|
|
|
|
- result.verts.push_back(points[ (i+1) * cnt_segments + seg + 1]);
|
|
|
|
- result.verts.push_back(points[ (i+1) * cnt_segments + seg]);
|
|
|
|
|
|
+ result.verts.push_back(points[ i * cnt_segments + (seg % cnt_segments)]);
|
|
|
|
+ result.verts.push_back(points[ i * cnt_segments + (seg + 1) % cnt_segments]);
|
|
|
|
+ result.verts.push_back(points[ (i+1) * cnt_segments + ((seg + 1 + best_pair_offset) % cnt_segments)]);
|
|
|
|
+ result.verts.push_back(points[ (i+1) * cnt_segments + ((seg + best_pair_offset) % cnt_segments)]);
|
|
|
|
|
|
result.vertcnt.push_back(4);
|
|
result.vertcnt.push_back(4);
|
|
}
|
|
}
|