예제 #1
0
파일: mesh.cpp 프로젝트: valdersoul/NoriV2
void Mesh::samplePosition(const Point2f &sample, Point3f &p, Normal3f &n) const {
    Point2f reusableSample = sample;
    //get a random face
    uint32_t faceIndex = m_dpdf->sampleReuse(reusableSample(0));


    // sample the triangle of the face
    Point2f uv = Warp::squareToTriangle(reusableSample);

    //get the vertex index
    uint32_t i0 = m_F(0, faceIndex), i1 = m_F(1, faceIndex), i2 = m_F(2, faceIndex);

    //get the points
    Point3f p0 = m_V.col(i0), p1 = m_V.col(i1), p2 = m_V.col(i2);

    //compute the edge vectors
    Vector3f edge1 = (p1 - p0);
    Vector3f edge2 =  (p2 - p0);
    Vector3f e1 = uv(0) * edge1;
    Vector3f e2 = uv(1) * edge2;

    //compute the new point
    p = p0 + e1 + e2;

    //compute the normal base on baycentric coordinates
    //get the vertex normals
    if(m_N.cols() > 3) {
        Normal3f n0 = m_N.col(i0), n1 = m_N.col(i1), n2 = m_N.col(i2);
        Vector3f w0 = p0 - p;
        Vector3f w1 = p1 - p;
        Vector3f w2 = p2 - p;

        float area = (edge1.cross(edge2)).norm();
        if(area != 0.0f){
            float u = (w0.cross(w1)).norm() / area;
            float v = (w1.cross(w2)).norm() / area;

            n = (1.0f - u - v) * n0 + v * n1 + u * n2;
            n.normalized();

        } else {
            n = (e1.cross(e2)).normalized();

        }
    } else {
        //no normals provided
        n = (e1.cross(e2)).normalized();
        if(isnan(n.sum())){
            cout << "Normal is nan" << endl;
            cout << "e1 " << e1 << endl;
            cout << "e2 " << e2 << endl;
        }
    }




    //n = uv(0) * n0 + uv(1) * n1 + (1.0f - uv(0) - uv(1)) * n2;

}
예제 #2
0
파일: mesh.cpp 프로젝트: valdersoul/NoriV2
float Mesh::surfaceArea(uint32_t index) const {
    uint32_t i0 = m_F(0, index), i1 = m_F(1, index), i2 = m_F(2, index);

    const Point3f p0 = m_V.col(i0), p1 = m_V.col(i1), p2 = m_V.col(i2);

    return 0.5f * Vector3f((p1 - p0).cross(p2 - p0)).norm();
}
예제 #3
0
void BoysFunction::setx(double x)
{
    if (x <= 50){
        m_F(m_nMax) = tabulated(m_nMax, x);
    } else {
        m_F(m_nMax) = asymptotic(m_nMax, x);
    }

    double ex = exp(-x);

    for(int n = m_nMax; n > 0; n--){
        m_F(n-1) = (2*x*m_F(n) + ex)/(2*n - 1);
    }
}
예제 #4
0
파일: mesh.cpp 프로젝트: valdersoul/NoriV2
bool Mesh::rayIntersect(uint32_t index, const Ray3f &ray, float &u, float &v, float &t) const {
    uint32_t i0 = m_F(0, index), i1 = m_F(1, index), i2 = m_F(2, index);
    const Point3f p0 = m_V.col(i0), p1 = m_V.col(i1), p2 = m_V.col(i2);

    /* Find vectors for two edges sharing v[0] */
    Vector3f edge1 = p1 - p0, edge2 = p2 - p0;

    /* Begin calculating determinant - also used to calculate U parameter */
    Vector3f pvec = ray.d.cross(edge2);

    /* If determinant is near zero, ray lies in plane of triangle */
    float det = edge1.dot(pvec);

    if (det > -1e-8f && det < 1e-8f)
        return false;
    float inv_det = 1.0f / det;

    /* Calculate distance from v[0] to ray origin */
    Vector3f tvec = ray.o - p0;

    /* Calculate U parameter and test bounds */
    u = tvec.dot(pvec) * inv_det;
    if (u < 0.0 || u > 1.0)
        return false;

    /* Prepare to test V parameter */
    Vector3f qvec = tvec.cross(edge1);

    /* Calculate V parameter and test bounds */
    v = ray.d.dot(qvec) * inv_det;
    if (v < 0.0 || u + v > 1.0)
        return false;

    /* Ray intersects triangle -> compute t */
    t = edge2.dot(qvec) * inv_det;

    return t >= ray.mint && t <= ray.maxt;
}
예제 #5
0
파일: mesh.cpp 프로젝트: valdersoul/NoriV2
Point3f Mesh::getCentroid(uint32_t index) const {
    return (1.0f / 3.0f) *
        (m_V.col(m_F(0, index)) +
         m_V.col(m_F(1, index)) +
         m_V.col(m_F(2, index)));
}
예제 #6
0
파일: mesh.cpp 프로젝트: valdersoul/NoriV2
BoundingBox3f Mesh::getBoundingBox(uint32_t index) const {
    BoundingBox3f result(m_V.col(m_F(0, index)));
    result.expandBy(m_V.col(m_F(1, index)));
    result.expandBy(m_V.col(m_F(2, index)));
    return result;
}
예제 #7
0
double BoysFunction::returnValue(int n)
{
    return m_F(n);
}
예제 #8
0
파일: pd_osp.cpp 프로젝트: ttnghia/PDtools
//------------------------------------------------------------------------------
void PD_OSP::calculateForces(const std::pair<int, int> &idCol)
{
    const int pId = idCol.first;
    const int col_i = idCol.second;
    const double a_i = m_data(col_i, m_indexA);
    const double b_i = m_data(col_i, m_indexB);
    const double d_i = m_data(col_i, m_indexD);
    const double theta_i = m_data(col_i, m_indexTheta);

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[3];
    double r0_i[3];
    double f_i[3];
    for(int d=0; d<m_dim; d++)
    {
        f_i[d] = 0;
        r_i[d] = m_r(d, col_i);
        r0_i[d] = m_r0(d, col_i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[3];

    double thetaNew = 0;
    for(int l_j=0; l_j<nConnections; l_j++)
    {
        auto &con = PDconnections[l_j];
        if(con.second[m_indexConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double a_j = m_data(j, m_indexA);
        const double b_j = m_data(j, m_indexB);
        const double d_j = m_data(j, m_indexD);
        const double theta_j = m_data(j, m_indexTheta);
        const double vol_j = m_data(j, m_indexVolume);
        const double dr0 = con.second[m_indexDr0];
        const double volumeScaling = con.second[m_indexVolumeScaling];
        const double a_ij = 0.5*(a_i + a_j);
        const double b_ij = 0.5*(b_i + b_j);
        const double d_ij = 0.5*(d_i + d_j);
        const double Gd_ij = con.second[m_indexForceScalingDilation];
        const double Gb_ij = con.second[m_indexForceScalingBond];

        double dr2 = 0;
        double A_ij = 0; // The lambda-factor

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
            A_ij += dr_ij[d]*(m_r0(d, j) - r0_i[d]);
        }

        const double dr = sqrt(dr2);
        A_ij /= (dr0*dr);
        double ds = dr - dr0;

        // To avoid roundoff errors
        if (fabs(ds) < THRESHOLD)
            ds = 0.0;

        const double s = ds/dr0;
        const double fbond = (a_ij*d_ij*Gd_ij*A_ij/dr0*(theta_i + theta_j) + b_ij*Gb_ij*s)
                *vol_j*volumeScaling/dr;
        for(int d=0; d<m_dim; d++)
        {
            f_i[d] += dr_ij[d]*fbond;
        }

        thetaNew += d_ij*s*A_ij*vol_j*volumeScaling;
        con.second[m_indexStretch] = s;
    }

    for(int d=0; d<m_dim; d++)
    {
        m_F(d, col_i) += m_delta*f_i[d];
    }

    m_data(col_i, m_indexThetaNew) = m_delta*thetaNew;
}
예제 #9
0
//------------------------------------------------------------------------------
void PD_LPS_porosity_adrmc::calculateForces(const int id, const int i) {
  const double theta_i = m_data(i, m_iTheta);
  const double m_i = m_data(i, m_iMass);
  const double a_i = m_data(i, m_iA);
  const double b_i = m_data(i, m_iA);

  vector<pair<int, vector<double>>> &PDconnections =
      m_particles.pdConnections(id);

  const int nConnections = PDconnections.size();
  double dr0_ij[m_dim];
  double dr_ij[m_dim];
  _F.zeros();

  double thetaNew = 0;
  int nConnected = 0;

  //----------------------------------
  // TMP - standard stress calc from
  //    m_data(i, m_indexStress[0]) = 0;
  //    m_data(i, m_indexStress[1]) = 0;
  //    m_data(i, m_indexStress[2]) = 0;
  //----------------------------------

  for (int l_j = 0; l_j < nConnections; l_j++) {
    auto &con = PDconnections[l_j];

    if (con.second[m_iConnected] <= 0.5)
      continue;

    const int id_j = con.first;
    const int j = m_idToCol_v[id_j];

    const double m_j = m_data(j, m_iMass);
    const double theta_j = m_data(j, m_iTheta);
    const double vol_j = m_data(j, m_iVolume);
    const double dr0 = con.second[m_iDr0];
    const double volumeScaling = con.second[m_iVolumeScaling];
    const double vol = vol_j * volumeScaling;
    const double w = weightFunction(dr0);
    const double a_j = m_data(j, m_iA);
    const double b_j = m_data(j, m_iB);

    double dr2 = 0;

    for (int d = 0; d < m_dim; d++) {
      dr0_ij[d] = m_r0(j, d) - m_r0(i, d);
      dr_ij[d] = m_r(j, d) - m_r(i, d);
      dr2 += dr_ij[d] * dr_ij[d];
    }

    const double dr = sqrt(dr2);
    const double ds = dr - dr0;
    double bond = (b_i * theta_i / m_i + b_j * theta_j / m_j) * dr0;
    bond += (a_i / m_i + a_j / m_j) * ds;
    bond *= w * vol / dr;
    thetaNew += w * dr0 * ds * vol;

    for (int d = 0; d < m_dim; d++) {
      m_F(i, d) += dr_ij[d] * bond;

      for (int d2 = 0; d2 < m_dim; d2++) {
        _F(d, d2) += w * dr_ij[d] * dr0_ij[d2] * vol;
      }
    }

    con.second[m_iStretch] = ds / dr0;
    //----------------------------------
    // TMP - standard stres calc from
    //        m_data(i, m_indexStress[0]) += 0.5*dr_ij[0]*dr_ij[0]*bond;
    //        m_data(i, m_indexStress[1]) += 0.5*dr_ij[1]*dr_ij[1]*bond;
    //        m_data(i, m_indexStress[2]) += 0.5*dr_ij[0]*dr_ij[1]*bond;
    //----------------------------------
    nConnected++;
  }

  if (nConnections <= 3) {
    m_data(i, m_iThetaNew) = 0;
  } else {
    m_data(i, m_iThetaNew) = m_dim / m_i * thetaNew;
  }

  //----------------------------------
  // TMP - standard stres calc from
  //----------------------------------
  //    if(nConnected > 5) {
  //        computeStress(id, i, nConnected);
  //    }
  computeStress(id, i, nConnected);
  //--------------------
  m_continueState = false;
}
예제 #10
0
파일: pd_lps.cpp 프로젝트: ttnghia/PDtools
//------------------------------------------------------------------------------
void PD_LPS::calculateForces(const std::pair<int, int> &idCol)
{
    const int pId = idCol.first;
    const int i = idCol.second;
    const double theta_i = m_data(i, m_iTheta);
    const double m_i = m_data(i, m_iMass);

    double alpha;
    if(m_dim == 3)
        alpha = 15*m_mu;
    else
        alpha = 8*m_mu;

    const double c = (3*m_k - 5*m_mu);

    vector<pair<int, vector<double>>> & PDconnections = m_particles.pdConnections(pId);

    double r_i[m_dim];
    double r0_i[m_dim];
    double f_i[m_dim];

    for(int d=0; d<m_dim; d++)
    {
        f_i[d] = 0;
        r_i[d] = m_r(d, i);
        r0_i[d] = m_r0(d, i);
    }

    const int nConnections = PDconnections.size();
    double dr_ij[m_dim];

    double thetaNew = 0;
    for(int l_j=0; l_j<nConnections; l_j++)
    {
        auto &con = PDconnections[l_j];

        if(con.second[m_iConnected] <= 0.5)
            continue;

        const int id_j = con.first;
        const int j = m_pIds[id_j];

        const double m_j = m_data(j, m_iMass);
        const double theta_j = m_data(j, m_iTheta);
        const double vol_j = m_data(j, m_iVolume);
        const double dr0 = con.second[m_iDr0];
        const double volumeScaling = con.second[m_iVolumeScaling];
        const double gb_ij = con.second[m_iForceScalingBond];
        const double gd_ij = con.second[m_iForceScalingDilation];

        double dr2 = 0;

        for(int d=0; d<m_dim; d++)
        {
            dr_ij[d] = m_r(d, j) - r_i[d];
            dr2 += dr_ij[d]*dr_ij[d];
        }

        const double dr = sqrt(dr2);
        const double ds = dr - dr0;
        double bond = gd_ij*c*(theta_i/m_i + theta_j/m_j)*dr0;
        bond += gb_ij*alpha*(1./m_i + 1./m_j)*ds;
        bond *= vol_j*volumeScaling/dr;
        thetaNew += dr0*ds*vol_j*volumeScaling;

        for(int d=0; d<m_dim; d++)
        {
            m_F(d, i) += dr_ij[d]*bond;
        }

        con.second[m_iStretch] = ds/dr0;
    }

    m_data(i, m_iThetaNew) = m_dim/m_i*thetaNew;
}