- IFC: avoid artifacts in high-curvature regions (or the boundaries thereof) of IfcSweptDiskSolid elements.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1299 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/6/merge
parent
a038288af9
commit
15c0b8b955
|
@ -581,6 +581,8 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
|||
startvec.y = 1.0f;
|
||||
startvec.z = 1.0f;
|
||||
|
||||
unsigned int last_dir = 0;
|
||||
|
||||
// generate circles at the sweep positions
|
||||
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,
|
||||
// try to maximize ||(p-q)|| * ||(p_last-q_last)||
|
||||
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();
|
||||
startvec = q;
|
||||
|
||||
// generate a rotation matrix to rotate q around d
|
||||
IfcMatrix4 rot;
|
||||
|
@ -630,12 +642,27 @@ void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, Conv
|
|||
// make quads
|
||||
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 ];
|
||||
|
||||
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]);
|
||||
// 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 % 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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue