bool inBox(const Vec3r& inter, const Vec3r& box_min, const Vec3r& box_max){ if(((inter.x()>=box_min.x()) && (inter.x() <box_max.x())) && ((inter.y()>=box_min.y()) && (inter.y() <box_max.y())) && ((inter.z()>=box_min.z()) && (inter.z() <box_max.z())) ){ return true; } return false; }
// precondition1: P is inside the sphere // precondition2: P,V points to the outside of the sphere (i.e. OP.V > 0) static bool sphere_clip_vector(const Vec3r& O, real r, const Vec3r& P, Vec3r& V) { Vec3r W = P - O; real a = V.squareNorm(); real b = 2.0 * V * W; real c = W.squareNorm() - r * r; real delta = b * b - 4 * a * c; if (delta < 0) { // Should not happen, but happens sometimes (numerical precision) return true; } real t = - b + ::sqrt(delta) / (2.0 * a); if (t < 0.0) { // Should not happen, but happens sometimes (numerical precision) return true; } if (t >= 1.0) { // Inside the sphere return false; } V[0] = (t * V.x()); V[1] = (t * V.y()); V[2] = (t * V.z()); return true; }
void FEdgeXDetector::preProcessFace(WXFace *iFace) { Vec3r firstPoint = iFace->GetVertex(0)->GetVertex(); Vec3r N = iFace->GetNormal(); // Compute the dot product between V (=_Viewpoint - firstPoint) and N: Vec3r V; if (_orthographicProjection) { V = Vec3r(0.0, 0.0, _Viewpoint.z() - firstPoint.z()); } else { V = Vec3r(_Viewpoint - firstPoint); } N.normalize(); V.normalize(); iFace->setDotP(N * V); // compute the distance between the face center and the viewpoint: if (_orthographicProjection) { iFace->setZ(iFace->center().z() - _Viewpoint.z()); } else { Vec3r dist_vec(iFace->center() - _Viewpoint); iFace->setZ(dist_vec.norm()); } }
// assume the point is inside the triangle Vec3r ComputeBarycentricCoords(const Vec3r A,const Vec3r B,const Vec3r C,const Vec3r P) { Vec3r BA = B-A; Vec3r CA = C-A; Vec3r N = BA^CA; Vec3r PA = A-P; Vec3r PB = B-P; Vec3r PC = C-P; double areaA = (PB^PC) * N; double areaB = (PC^PA) * N; double areaC = (PA^PB) * N; #if 0 // checking printf("Barycentric debug: ----------------------------------\n"); printf("A = [%f %f %f], B = [%f %f %f], C = [%f %f %f]\n", A.x(), A.y(), A.z(), B.x(), B.y(), B.z(), C.x(), C.y(), C.z()); printf("P = [%f %f %f]\n", P.x(), P.y(), P.z()); printf("areas = [%f %f %f]\n", areaA, areaB, areaC); printf("plot3([%f %f %f %f],[%f %f %f %f],[%f %f %f %f],'r-');\n", A.x(), B.x(), C.x(), A.x(), A.y(), B.y(), C.y(), A.y(), A.z(), B.z(), C.z(), A.z()); printf("hold on; plot3(%f,%f,%f,'bo');\n", P.x(),P.y(),P.z()); #endif assert(areaA > -0.1 && areaB > -0.1 && areaC > -0.1); if (areaA < 0) areaA = 0; if (areaB < 0) areaB = 0; if (areaC < 0) areaC = 0; double totalArea = areaA + areaB + areaC; double a = areaA / totalArea; double b = areaB / totalArea; double c = areaC / totalArea; // printf("c = [%f %f %f]\n", a,b,c); Vec3r result(a,b,c); return result; }
void FEdgeXDetector::ProcessSilhouetteFace(WXFace *iFace) { // SILHOUETTE LAYER Vec3r normal; // Compute the dot products between View direction and N at each vertex of the face: Vec3r point; int closestPointId = 0; real dist, minDist = FLT_MAX; int numVertices = iFace->numberOfVertices(); WXFaceLayer *faceLayer = new WXFaceLayer(iFace, Nature::SILHOUETTE, true); for (int i = 0; i < numVertices; i++) { point = iFace->GetVertex(i)->GetVertex(); normal = iFace->GetVertexNormal(i); normal.normalize(); Vec3r V; if (_orthographicProjection) { V = Vec3r(0.0, 0.0, _Viewpoint.z() - point.z()); } else { V = Vec3r(_Viewpoint - point); } V.normalize(); real d = normal * V; faceLayer->PushDotP(d); // Find the point the closest to the viewpoint if (_orthographicProjection) { dist = point.z() - _Viewpoint.z(); } else { Vec3r dist_vec(point - _Viewpoint); dist = dist_vec.norm(); } if (dist < minDist) { minDist = dist; closestPointId = i; } } // Set the closest point id: faceLayer->setClosestPointIndex(closestPointId); // Add this layer to the face: iFace->AddSmoothLayer(faceLayer); }
bool intersectRayBBox(const Vec3r& orig, const Vec3r& dir, // ray origin and direction const Vec3r& boxMin, const Vec3r& boxMax, // the bbox real t0, real t1, real& tmin, real& tmax, // I0=orig+tmin*dir is the first intersection, I1=orig+tmax*dir is the second intersection real epsilon){ float tymin, tymax, tzmin, tzmax; Vec3r inv_direction(1.0/dir[0], 1.0/dir[1], 1.0/dir[2]); int sign[3]; sign[0] = (inv_direction.x() < 0); sign[1] = (inv_direction.y() < 0); sign[2] = (inv_direction.z() < 0); Vec3r bounds[2]; bounds[0] = boxMin; bounds[1] = boxMax; tmin = (bounds[sign[0]].x() - orig.x()) * inv_direction.x(); tmax = (bounds[1-sign[0]].x() - orig.x()) * inv_direction.x(); tymin = (bounds[sign[1]].y() - orig.y()) * inv_direction.y(); tymax = (bounds[1-sign[1]].y() - orig.y()) * inv_direction.y(); if ( (tmin > tymax) || (tymin > tmax) ) return false; if (tymin > tmin) tmin = tymin; if (tymax < tmax) tmax = tymax; tzmin = (bounds[sign[2]].z() - orig.z()) * inv_direction.z(); tzmax = (bounds[1-sign[2]].z() - orig.z()) * inv_direction.z(); if ( (tmin > tzmax) || (tzmin > tmax) ) return false; if (tzmin > tmin) tmin = tzmin; if (tzmax < tmax) tmax = tzmax; return ( (tmin < t1) && (tmax > t0) ); }